#ask How should we improve Motoko?

@jzxchiang, actually, imperative data structures are compatible with stable variables. What isn’t are object-oriented abstractions, because of the functions embedded in the data. But that is an independent dimension, as objects can be either imperative or functional.

To wit, here is a toy example of a counter object that, although functional, cannot be put in a stable var:

class Counter(x : Nat) {
  public func get() : Nat { x };
  public func inc() : Counter { Counter(x + 1) };
};

stable var c : Counter = Counter(0);   // ERROR

On the other hand, here is an imperative counter type that you can store in a stable var just fine:

type Counter = {var count : Nat};
func Counter(x : Nat) : Counter { {var count = x} };
func get(c : Counter) : Nat { c.count };
func inc(c : Counter) { c.count := c.count + 1 };

stable var c : Counter = Counter(0);  // ok

Of course, that doesn’t eliminate the dilemma, but it is rather between choosing object-oriented and “procedural” interfaces.

2 Likes

Right, but once you loosen it like that, the intent is no longer visible in the code. It might or might not be an accident.

In my experience (e.g. in OCaml), the strict rule is good documentation and uncovers many mistakes early on. The occasional ignore in cases like replace is a fair deal in exchange. But like option types, it’s one of these features that you have to learn to “hold right”. When you are working against it (perhaps out of habit) you can end up with repetitive strain injury.

2 Likes

I don’t want to be deciphering the documentation.

What I need :slight_smile:

What I get :frowning:

Also, Add a “New developper start here” button with Dr Angela Yu uDemy Web3 video featuring ICP and Motoko. Would have save me a ton of hours searching for basic info as a newbie.

5 Likes

We 100% should have a https://embed.smartcontracts.org/ example for each of the functions in base.

4 Likes

That’s a really good idea…

I’ll build an MVP to show the team, and we’ll see what happens from there.

3 Likes

It’d be cool if we could omit optional record fields.

Screen Shot 2022-11-07 at 9.47.56 PM

4 Likes

That’s ends up creating a totally different type and reworking the meaning of an optional type into something more JavaScripty though, right?

You can always narrow

  type OptionalArgsABC = { a : ?Text; b : ?Text; c : ?Text };
  let optionals : OptionalArgsABC = { a = ?"maybe"; b = ?"is"; c = null };

  type OptionalArgsAB = { a : ?Text; b : ?Text };
  let { a; b }: OptionalArgsAB = optionals;

@tomijaga What’s the common use case you have in mind?

1 Like

@icme Lets say we have a method that accepts parameters as the first argument

public shared func myMethod(params: {
  paramA: ?Nat;
  paramB: ?Nat;
  paramC: ?Nat;
  paramD: ?Nat;
  paramE: ?Nat;
})

All of the parameters are optional. I want to call this method, but I only need to pass paramA

myMethod({ paramA = ?1; paramB = null; paramC = null; paramD = null; paramE = null });

Not very convenient as I still need to specify all of the parameters even if I don’t need them. With the latest features, though, I can do this

let defaultParams = { paramA = null; paramB = null; paramC = null; paramD = null; paramE = null };

myMethod({ defaultParams with paramA = ?1 });

A lot better but still requires defaultParams to be declared on the side of a caller

2 Likes

I could see this as a good class constructor scenario as well.

Record extension syntax works for now, but at least that is explicitly saying what the defaults are - it sounds like with this feature you’d like the defaults to implicitly be null.

1 Like

some better vscode tooling would be really nice

@ZhenyaUsenko explained the use case I had in mind.

Yes, that is right.
I was thinking about the user experience when calling a function that takes a record with many optional fields.
An example would be initializing the ICRC-1 token, where some fields are optional and have default values set, so they don’t need to be specified by the user.
This was the Initial type, but I updated it later to the one below because there were too many optional types.

        let token = Token.Token({
            ... 
            min_burn_amount: ?Nat;
            minting_account: ?Account; 
            permitted_drift: ?Nat;
            transaction_window: ?Nat; 
            burned_tokens: ?Nat 
        });

I moved the fields least likely to be specified by the user into an optional record called advanced_settings.

        let token = Token.Token({
            ... 
            min_burn_amount: Nat;
            minting_account: ?Account; 
            advanced_settings: ?{
                permitted_drift: Nat;
                transaction_window: Nat; 
                burned_tokens: Nat;
            };
        });

Also, it seems like motoko supports this functionality for serializing partial records encoded in candid.

Hey @nolyoi, what types of tools are you referring to?

Also, are you aware of the vscode extension the dfinity team is working on?

1 Like

Auto generated CLI args. For example you write this function:

public shared func registerUser(handle : Text, displayName : Text) : () {
...user registration
return
}

Then we could run a dfx command to generate an example command line argument, dfx canister call Canister1 registerUser --example-cli-arg, which could return:

dfx canister call Canister1 registerUser '("handle" : text, "displayName" : text)'

This is actually supported. You can use dfx canister call Canister1 registerUser --random '' to generate a random value of that type. You can even customize the random value, e.g., use --random '{text = Some "name"}' to generate a random name. The spec of the random config is here: candid/config.md at master · dfinity/candid · GitHub

4 Likes

The Motokodoc is great. Is it possible to have auto-generation/snippet hotkey that fills out each part of a function’s signature as a template? And then an option to hide all unless on hover/specifically selected?

Might be worth autolinking to the corresponding comments in the Candid file as well.

1 Like

Great idea! I’ll add some doc comment snippets right now.

Here’s the source file in case anyone is interested in contributing code snippets to the VS Code extension and Motoko Playground:

I have no clue what this is…what does this do and how do you use it?