Open Leu-Gim opened 6 years ago
Now I see (..)`` are used already for objects matching, so maybe just to pick some syntax not used for anything (
!(...)` ?).
Yeah, that's important.
@krux02 had the idea to use backtick as in scala (http://kishorelive.com/2011/11/02/backticks-in-scala/) in his lib, I think that makes sense for gara too: but not only for labels, for various expressions as in your example.
of (e: `(f: 2)`): ..
would match only a tuple (f: 2)
If we do it for variables too, we can even think of removing @name
and using just name
for capture .. I actually like @name
tho, it makes it obvious when you capture
Backticks seem though be a limiting choice. They are used in Nim and may be needed inside expressions, and as they don't have open/close pairs, as parentheses, so either some escaping means will be needed, which is both not pretty and syntax-breaking, or to give up on possibility to use backticks inside, then expressions are both limited and somewhat special-case'ed; in both cases they are not just "Nim expressions", somewhat more special.
With (...)
, [...]
or {...}
no such problems arise, you don't care what users will use in those expressions - what's correct for Nim is correct in them; they have to be paired in Nim already.
Yet problems with backtick and other non-pair delimiters: they generally cannot be matched in editors (like highlight matching parentheses); their contents may be syntax-highlighted as a whole (as for strings), and maybe somebody uses it already for backticks (representing variables); if not, then easy to leave not-closed, or close twice, or use occasionally inside, wich breaks its limits, as occured for my previous post. :)
proc `+`(a, b: int): int = 42 # so users may need "system.`+`" later in code
of (e: `(f: system.`+`(2, 2))`) # breaks! and worse: may be even parsed, but not as expeected,
# making hard to debug
of (e: !{(f: system.`+`(2, 2))}) # no special syntax or special awareness for code inside "!{...}",
# and no problems
!{...}
is just for an example, same for !(...)
, if curlies {...}
are not used by patterns, they may work for this by themselves (no !
).
I agree it's not perfect, but it seems as a more natural notation compared
The problem with the other ones is that
{}
for sets and its ambigious when you have {a}
: is it the variable a? is it a set of a ?[]
are reserved for array matching in a similar way()
seems very confusing: it's usually "grouping" and it's already overloaded for tuples/objects!{}
seems kinda ok, but I am really hesitant to add a new symbol after @
Something else I can do is
name
and fields name.field
without any additional escaping : they don't clash with patterns (this is already happening for some literals and names)!{}
) for other less common cases Calls and binary expressions seem to be the only other really common cases
Calls can be also supported directly if they don't clash with the name(..)
pattern which means: they are not named as another type and there is not a name(argType)
function with their name used for unpacking.
Most binary expressions should be supportable: a + b
or a - b
etc probably wouldn't be pattern syntax. Only and
and or
/ |
are probable clashes
Of course one would be always able to use the !{}
with them
The last point is: I want to be able to support powerful unification:
(a: @name, b: @other, c: expression(@name, @other)) should kinda work e.g.
(a: @name, b: @b, c: @name - @b)
but basically this just requires us to check for @label
in those "literal" expressions
I think if quotation is supported and with full Nim's syntax allowed inside (!{}
),
then some clashes w/o it are ok,
just everything special-cased outside of !{}
should be listed in docs in one place.
(a: @name, b: @b, c: @name - @b)
- cool.
Could such previous captures be accessible in some way yet inside quotations?
Though I don't know how, if code in !{}
is a plain Nim expression (@
not special-cased).
@...
for captures looks ok for me;
I'd also like additionally of C(e: E(f: @f) as e):
(SQL-like) for of C(e: E(f: @f) @e):
,
but it would not work for f
in this example.
I try to use ranges as patterns, and they don't work now:
let a = 3
match(a):
of 2..3:
echo 1
While ranges as a much common case would be desired to be used just directly, still generally qouted expressions resulting in types would be of use. Like:
of !{2..3}:
That is it's result is checked not only with ==
, but also with is
.
Is this planned?
Yes, all captures should be available in expressions after them.
as
sounds cool, but I want to use the same syntax for capturing everywhere, I'll think about it
ranges are going to have first class support too
!{}
If I correctly understood what you mean, you could use some special syntax then for evaluation, like
of eval 2 + 2: ...
orof (2 + 2): ...
(even both these syntaces at the same time), still reservingof 2 + 2: ...
for some patterns' syntax.Actually it would be just a special syntax for evaluation, and it could be used inside patterns syntax:
of (2*2) * (3*3): ...
- here2*2
and3*3
are evaluated, and*
between them is for some patterns' syntax applied to their results.