MWEL questions

A few questions:

  • In variable definitions, are two quotes are needed for strings: “‘random_without_replacement’” etc. ?

  • what do the two types of quotes (double and single) do?

  • What does the semicolon do?

  • I see in some variable defns you have
    var sync (default_value = 0)
    and others have
    var sync = 0
    Difference?

  • Do you have a code highlighting style you use? Javascript? C with linux-style braces?

  • It appears that expressions to the right of equals signs are sometimes interpreted differently:
    when = timer_expired(t)
    duration_units = ms
    variable1 = variable2
    Are these all part of a unified expression language that I’m not putting together?

thanks,
Mark

Hi Mark,

what do the two types of quotes (double and single) do?

It’s just like Python: There’s no semantic difference between the two. It’s just a matter of preference or convenience (e.g. when you want a string with embedded quotes of one type, delimit the string with the other type).

What does the semicolon do?

If you want to specify multiple component parameters on a single line, you separate them with semicolons.

I see in some variable defns you have var sync (default_value = 0) and others have
var sync = 0. Difference?

The second is shorthand for the first.

The first form is an example of the general component declaration syntax, which you must use if you want to specify more than just the default value for a variable.

In variable definitions, are two quotes are needed for strings: “‘random_without_replacement’” etc. ?

They aren’t in assignment-style variable declarations:

var a = 'Hello, world!'

However, they are needed when you use component-declaration syntax:

var a (default_value = "'Hello, world!'")

The reason for this is that the MWEL-to-XML translator strips quotes from parameter values. This is needed because most MWorks components expect to receive “raw” text (and not quoted strings) for their parameters. For example,

run_python_string ('x = 3')

is converted to

<action type="run_python_string" code="x = 3"/>

If the translator didn’t strip the quotes, then the XML would contain code="'x = 3'", and the Python “code” would be 'x = 3' (i.e. a string literal). Does that make sense?

The basic issue is that, in general, the MWEL-to-XML translator doesn’t know whether a parameter value will be treated as an expression or as “raw” text. However, in the case of assignment-style variable declarations (and also actual assignments), it does know that the value to the right of = is an expression; if the value is a quoted string, the quotes are not stripped.

I know this a wart, but I don’t see a good way to avoid it.

Do you have a code highlighting style you use? Javascript? C with linux-style braces?

Do you mean a code formatting style?

MWEL doesn’t give you as much freedom as C-like languages. For example, every statement must end with a newline, and newlines are not permitted between the signature/tag and the parameter list, or between the parameter list and children, in component declarations. In other words, this is correct:

if (x) {
    report ('x is true')
}

but these are invalid syntax:

if  // ERROR: parameter list can't start on next line
(x) {
    report ('x is true')
}

if (x)  // ERROR: children can't start on next line
{
    report ('x is true')
}

However, unlike Python, indentation is not significant.

I like the formatting style I use in the docs and in the examples I’ve sent you, but you’re free to come up with your own (within the limits of the syntax).

If you’re asking about syntax highlighting modes in a text editor, I have a very rudimentary MWEL mode for Sublime Text. It doesn’t do much at the moment, but I’m hoping to make it better (eventually).

It appears that expressions to the right of equals signs are sometimes interpreted differently: when = timer_expired(t) , duration_units = ms, variable1 = variable2. Are these all part of a unified expression language that I’m not putting together?

It’s very similar to how Python uses = for both variable assignments and keyword arguments in function calls. This assigns the value of variable y to variable x:

x = y

Whereas this declares a goto transition with parameters target and when:

goto (
    target = NextState
    when = timer_expired(MyTimer)
    )

// Equivalent:
goto (target = NextState; when = timer_expired(MyTimer))

Chris

OK, great. I didn’t see the MWEL documentation page, which is excellent, until now.

If you want to specify multiple component parameters on a single line, you separate them with semicolons.

OK.

run_python_string (‘x = 3’)
is converted to

If the translator didn’t strip the quotes, then the XML would contain code=“‘x = 3’”, and the Python “code” would be ‘x = 3’ (i.e. a string literal). Does that make sense?

I know this a wart, but I don’t see a good way to avoid it.

This is a hairy wart, and one that I can’t wrap my head around easily.
In:

run_python_string (‘x = 3’)
isn’t it true that the the Python ‘code’ is a string? If so, if run_python_string gets a string as code, shouldn’t it be able to run it?

My question about equals below was spurred by trying to understand when an expression is expected and when not.

Do you mean a code formatting style?

I meant a syntax highlighting style, yes. Thanks for the details on the whitespace restrictions of MWEL.

It appears that expressions to the right of equals signs are sometimes interpreted differently: when = timer_expired(t), duration_units = ms, variable1 = variable2. Are these all part of a unified expression language that I’m not putting together?

It’s very similar to how Python uses = for both variable assignments and keyword arguments in function calls. This assigns the value of variable y to variable x:

I get this now after reading the web page - component declarations have parameters.

I was also trying to understand whether with duration_units=, ‘ms’ is treated as an expression or not. Your above explanation starts to help with that.

Thanks,
Mark

Hi Mark,

This is a hairy wart, and one that I can’t wrap my head around easily. In run_python_string ('x = 3') isn’t it true that the the Python ‘code’ is a string? If so, if run_python_string gets a string as code, shouldn’t it be able to run it?

run_python_string could be modified to accept either “raw” text or a string-valued expression (just like the address parameter of an NE-500 device does). But in general, MWorks components can go either way, and the MWEL-to-XML translator doesn’t know what they expect. It defaults to providing raw text, as more component types expect that.

I can think of a couple ways we might improve things:

  1. In MWComponents.yaml files, explicitly mark parameters that accept expressions. (Actually, this wouldn’t be a 100% fix in the case of variables, since default_value is interpreted as a generic expression only if type is any. Maintaining backward compatibility is such a bummer sometimes.)

  2. Add a special kind of string literal that isn’t unquoted – sort of like Python’s raw strings, except that the “raw” part is the quotes. While we could choose one of the existing quote forms (’ or ") to not be unquoted, I think that might be confusing. On the other hand, adding a third quote style might be just as confusing.

  3. Since this issue mainly pertains to default values of variables, we could extend the var syntax so that you could have parameters and an equals sign.

For example:

var x (scope = local) = 3

var y (persistant = YES) = 4 {
    report ('y = $y')
}

None of these options seem particularly great to me. What do you think?

Chris

Hi Mark,

FYI, I implemented a slightly-modified version of my previous idea for extending MWEL’s variable-declaration syntax. Now, instead of doing this:

var x (
    default_value = '"foo"'
    persistant = YES
    ) {
    report ('x = $x')
}

which requires the default value to be quoted twice in order to use a string literal, you can do this:

var x = 'foo' (persistant = YES) {
    report ('x = $x')
}

which requires only a single pair of quotes.

Even better, the same syntax can be used on a macro invocation, provided that the macro body consists of a single variable declaration. Hence, you could do something like this:

%define saved_var ()
    var (persistant = YES)
%end

saved_var x = 'foo' {
    report ('x = $x')
}

saved_var y = 7

and save yourself the embarrassment of repeatedly misspelling “persistent”. (FYI, it’s on my to-do list to fix that, in a backwards-compatible way, hopefully soon!)

Cheers,
Chris