related, I wish there was a scribble form for documenting syntax classes and their attributes
there is, internally. I added it somewhere
(To be clear, the form for documenting syntax class was there already, but it didn’t support specifying attributes. Supporting attributes is what I added)
Is there a rule of thumb for deciding when to define attributes for a syntax class and when to define a transformation using syntax-parse
?
if there’s a possibility of writing repetitive code for just one body of a function, should I write a macro for it? eg: (define (sql-row->person row #:order [order #(id name age number employer address ...)])
(define h
(for/hash ([(k v) (in-dict order)])
(values v k)))
(define (get key [default #f])
(if (dict-has-key? order key)
(vector-ref row key)
default))
(define id (get 'id))
(define name (get 'name))
...
;; rest of procedure
)
Can you write a function instead?
i mean yes i guess “functions are better and you should avoid macros when you can” is something i just remembered reading
i think im very lazy seeing those (define identifier (get ’identifier)) and thinking “well well isn’t that just #'(define name (get 'name))
” and can even be #'(define name
(if (dict-has-key? order 'name)
(vector-ref row 'name)
default-expr))
and so it’s more a question of if i should… because im thinking that way a procedure wouldn’t be built (get
), so it goes “faster” but that speed gain must be insignificant honestly… i think i need to change my mentality if anything
Yes, that’s one case where you could legitimately use a macro: (define-simple-macro (define-get id:id) (define id (get 'id)))
(untested)
then just write (define-get name)
maybe define/get
would be more idiomatic
It’s likely that speed is not going to be the first issue here indeed
(It’s legitimate because you’re playing with identifiers)
Is there a way for a lang like #lang pollen
by @mbutterick to communicate that it uses a non-@
“command character”? Such that a tool could pass that to make-scribble-lexer
https://docs.racket-lang.org/syntax-color/index.html#%28def._%28%28lib._syntax-color%2Fscribble-lexer..rkt%29._make-scribble-lexer%29%29 ? (I mean, ideally I’d like for there to exist such a way, and for module-lexer
to use that to call make-scribble-lexer
automatically. And so, this might end up being a PR. But first I’m double-checking, is there some get-info
or other means to communicate the non-standard command character. Or is that another PR.)
(By “a tool”, I mean DrRacket or Racket Mode, etc.)
is define-simple-macro
supposedly to be require
’d by for-syntax
? right? i get an error even though i have (for-syntax racket/syntax
syntax/parse
syntax/parse/define)
which of course only syntax/parse/define
provides define-simple-macro
… but idk im confused
it’s also in top level
(require syntax/parse/define)
yes, requires for macro can be a little confusing at times :slightly_smiling_face:
but why is it a runtime thing?
what…
When you use define-simple-macro
itself, you don’t use it inside a for-syntax
, so you shouldn’t require it for-syntax
i see, so because it’s a macro itself that expands to a define-syntax?
yes
but doesnt it mean it is a 0-level macro and the calls to it doesnt convert to a perfomance boost/compile-time transformation?
You can test this by compiling your program with raco make ...
you’ll see whether it has been transformed or not
i see…
should i define macros inside of functions? or is it better to have them on top level
For Pollen specifically, you can read pollen.rkt
’s setup
submodule and read the value of command-char
: https://docs.racket-lang.org/pollen/Setup.html#%28def._%28%28lib._pollen%2Fsetup..rkt%29._setup~3acommand-char%29%29
better at top level
mmm… ill do that raco make thing. how do i debug bytecode though?
Note that the value is user-customizable. I often set it back to @
.
I don’t think it’s a business of DrRacket or Racket Mode to be aware of Pollen’s convention, though.
either way thank you for answering and clearing my doubts :blush:
oh sorry, I meant raco expand ...
raco make
will give you bytecode indeed
ooh ok
If your macro usage is truly local to one function, defining a macro inside a function works too.
It works, but it can get tricky for the compiler no?
(in the sense of efficiency)
I don’t see why it’s going to be much more inefficient than the usual macro. Plus, it’s done at compile-time anyway.
i mean in this case it’s less about efficiency and more “i’m too lazy to type”
@sorawee ok the compiler is smarter than I thought :slightly_smiling_face:
(I thought it could be bothered by things like keywords or optional args)
If an editor tool uses a lexer to do syntax highlighting and indentation, it needs to know about scribble and the “command char”. e.g. Is @foo
to be lexed/colored as a symbol or as text. And the indentation convention for scribble are different than plain sexps (as implemented by e.g. DrR).
So AFAICT it’s pretty crucial to know what is the “command char”, for those things to work.
(Generally Racket is pretty awesome in enabling a lang to supply this information directly. There are just a couple “holes” I’ve found so far. One is this.)
(Another is telling a lexer colorer about “delimiter pairs” that might be other than parens, braces, brackets. Currently this seems to be configuration external to the language itself. The only example of that I’ve found so far is “ProfessorJ”.
So the paradigm there seems to be, “A ‘language’ is drscheme:tool
code loaded by DrRacket’s Choose Language command” — as opposed to, “A module language entirely determined by #lang
and get-info
”. I think? If so, this makes it unsuitable for use outside DrRacket (and not entirely satisfactory for lang implementors, either, I think?).
I’m guessing that just predates the concept of a module language.
You probably know this, but custom languages can provide color lexers that tools can access. Could Racket Mode use that to highlight custom language code on the fly? Would it be too slow?
Oh, whoops, I went searching for docs and totally missed your latest comments above.
> I’m guessing that just predates the concept of a module language. At least it predates submodules.
Introducing an “indentation time” in analogy to “documentation time” (for-doc) would be an interesting way of communicating how forms are to be indented.
Are you looking at introducing support for at-expressions to the racket-mode indenter?
I have a branch for Racket Mode that uses a lang-supplied lexer. It needs a lot of work but I’ve been dog-fooding it for awhile, on and off.
It’s been working well for syntax highlighting.
Indentation is tricky because the status quo get-info
returns a drracket:indnetation
and that presumes a GUI framework text<%>
, which won’t really work well for e.g. Racket Mode.
So I’ve been fleshing out a non-GUI alternative, to offer as a proposal.
TL;DR if you write an indenter, you usually want it to work on an already-lexed data structure with a few basic operations like “up expression”, “next expression”, etc.
The text<%>
interface offers that… but also pulls in a whole bunch of other, “heavy”, GUI things.
I need to find some time to write some prose about all this. Probably not a blog post, yet, because one goal of writing it down is for Robby to help point out things I’ve misunderstood, so I can revise it. :smile:
Oh, also, I want to make it work well for non-sexp langs. As I mentioned above it I think the status quo is a bit weak for that, IIUC.
Not that I really love non-sexp langs, but if people going to make them, I’d like to support them. :smile:
Lately I have used at-expression to generate JavaScript using React components (via Urlang). It looks like this:
If you need #langs to test with north
has a fairly weird custom lang (that comes with a color lexer).
In a nested at-expression like @foo[
@bar[ ...]]
The current (I think it is current) racket-mode indenter wants to indent it like: @foo[
@bar[ ... ]]
Similarly in pairs like: name1: property1
name2: property2
name3: property3
the second line is indented like this: name1: property1
name2: property2
name3: property3
fortunately, after indenting line2 manually, line 3 and forth is indented as I want it.
Note: This is just a data point - I know the current idententer doesn’t hanle at-expressions.
Ugh I just realized I posted this in #beginners not #general. Sorry all. Maybe I should step away from the keyboard for awhile.
No worries.
Hello, why does scribble strip out the underscore in this bit of code @defthing[_internal-allocation-type ctype?]{What?}
?
> _id typesets as id, but colored as a variable (like racketvarfont); this escape applies only if _id has no for-label binding and is not specifically colored as a subform non-terminal via defform, a variable via defproc, etc.
So it looks like if you require for-label
the identifier, it should work fine?
Hmm - I see; at the moment the bindings which is probably the issue.
Thank you; the behaviour is super surprising to me based on the documentation for defthing
@thurtu811 has joined the channel