-
So, I'm about to introduce pragmas to Teal (like Haskell's https://wiki.haskell.org/Language_Pragmas), to deal with the language evolution and environment differences in a more modular/gradual way (also inspired by https://github.com/seanbaxter/circle/blob/master/new-circle/README.md#versioning-with-feature-directives). See #723 (comment) for more Teal context) But, unusually this time, I'm not feeling too inspired about the syntax bikeshedding part. I feel like it should be a "special comment" a la Haskell, but I'm not sure how they should look. (I find Haskell's uppercase LANGUAGE keyword a bit jarring) In Teal, per-module pragmas will correspond to CLI compiler flags. For example, --feat-arity=on enables optional argument markers for stricter arity checks in function calls. Right now it's implemented (https://github.com/teal-language/tl/pull/750/files) as
but I think it should be more distinct. Perhaps one of these?
Some combination of the above? Something else entirely? Any ideas? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 8 replies
-
On the options indeed I think using a "pragma" prefix is a more sustainable approach so I would advocate more on this specific idea. Another possible one could be creating a specific syntax (since this isn't really just a comment) that would already imply pragmas, like taking the multicomment syntax, but using --[#[
arity on
something off
another_thing on
]#] |
Beta Was this translation helpful? Give feedback.
-
I'm a big fan of how Circle does it so I think this is a good direction for something like Teal to take. To suggest something non-specific, I'm not a huge fan of it being in what looks like a normal
I'm partial to Ada's pragmas where it's just pragma Feature (Arity => On) and Rust as well #![feature(arity)] but I do like the function call-esque syntax of these so maybe something like
or to go off the deep end and try to actually imitate a function call
Not super attached to any of these in particular, just my 2¢ on the bikeshed |
Beta Was this translation helpful? Give feedback.
-
Thank you all for the replies! The discussion helps clarifying the decision criteria! Looking at all the suggestions, one bit that stood out to me is that one thing I would put as a requirement is that it needs to be very easy to parse at the lexer stage. What I mean by that: the Teal compiler does a lexer pass where it builds a list of tokens, then a parser pass where it builds a tree, then a typechecker pass where it traverses the tree. Even though in #750 I handled the pragma syntax at the parser pass and the pragma semantics at the typechecker pass, a pragma can potentially modify the lexer pass itself (e.g. by adding a new operator). So in practical terms, we may need to "parse during the lexer", so the simpler the structure is, the better. I think that requirement rules out both using a plain soft-keyword such as Now whether to do it as a pseudo-comment or not, I'm leaning on "yes" because it avoids taking up an unused sigil. And comments are handled at the lexer stage, so it fits the mental model of being something "outside of the parse tree". Another point to keep in mind is to avoid confusion between pragmas and annotations. Things like Rust attributes (and its predecessor, C# attributes) attach to tree nodes. Pragmas are more like global compiler knobs (I mean, module-level at least). So these options are on the table:
As a side-note, maybe I'm just too new to Rust, but for some reason I always forget what's the right syntax for (One might argue that the |
Beta Was this translation helpful? Give feedback.
-
It seems people like the syntax to be more Lua-ish and possibly function-call-ish. How about this:
and would people be okay with the fact this is not real Lua/Teal evaluation? (ie, that |
Beta Was this translation helpful? Give feedback.
-
Stepping back a little to look at the big picture, if this is the goal: (quoting myself)
...then adding a pragma might not be the right solution, because, for example, the module using the old arity rules will not have the annotation. It would make more sense to load the old module with compat options, say, just as an example, like: -- just an example, I'm not advocating this
local old_module = require("old_module", { arity = off }) At that point, instead of being fine-grained like However, another goal that inspired me to explore pragmas was to: (quoting myself again)
That is, so I can introduce experimental disabled-by-default changes to the language, and for that I think pragmas in the code would make sense. So, right now, I'm thinking the best combo would be:
|
Beta Was this translation helpful? Give feedback.
-
I'm a bit late to the conversation, but perhaps you could take some inspiration from luacheck: for _, elem in ipairs(node:select(query)) do -- luacheck: ignore 512
do return elem end
end (example from here): -- luacheck: push ignore foo
foo() -- No warning.
-- luacheck: pop
foo() -- Warning is emitted. So an example for teal: -- teal: enable arity
-- teal: push disable arity
-- ... some code ...
-- teal: pop |
Beta Was this translation helpful? Give feedback.
I have just updated the pragmas PR so that the following works:
...and the arity-off rules apply to functions exported by
old_module
even when called from within arity-on parts of the code (because the old_module does not have?
annotations). See the test cases for full examples.This should make it easier for people to switch to new arity rules gradually!