scolobb-slack
2020-4-26 11:09:13

Thanks for the links! I’ll take a look at these over the next few hours


d_run
2020-4-26 14:27:51

is there an equivalent of gofmt for Racket laying about anywhere?


soegaard2
2020-4-26 14:29:10

Not directly. I think the closest is to open the file in DrRacket/Emacs, mark the whole buffer and then indent all.


sorawee
2020-4-26 14:34:49

pocmatos
2020-4-26 16:05:57

Everyone, a quick reminder tomorrow is virtual ELS streamed through twitch. With several interesting presentations, among those a keynote by Andy Keep on the nano pass framework https://www.european-lisp-symposium.org/2020/\|https://www.european-lisp-symposium.org/2020/


soegaard2
2020-4-26 16:08:00

9 am cet?


scolobb-slack
2020-4-26 17:15:29

OK, so my problem is I don’t know how Typed Racket is structured. Where should I begin reading the code to get started?


pocmatos
2020-4-26 17:31:55

Yes - Switzerland time.


soegaard2
2020-4-26 17:32:22

Excellent.


samdphillips
2020-4-26 17:51:06

Just reading the Framework docs, it seems like there is a lot of functionality that is spread out over the pages. A summary/table of mixins, interfaces and concrete classes would be helpful I think.

I keep thinking about how “discoverable” things are in a Smalltalk image or even how it’s a bit easier (for me) to understand and browse a Java API reading the Javadoc.


spdegabrielle
2020-4-26 17:53:25

I think DrRacket was once described as a tower of mixins or something like that


samth
2020-4-26 17:57:27

scolobb-slack
2020-4-26 18:09:29

That looks a like a big introduction! This a hugely important documentation material, I’m glad it exists. I’ll watch it over the next few days, thank you


samdphillips
2020-4-26 18:22:14

You don’t say …


samdphillips
2020-4-26 18:22:57

(that’s what I have in this toy I’m working on so far)


samth
2020-4-26 20:26:17

@greg sadly, changes to racket-mode mean that now when I break Typed Racket it breaks Racket mode :disappointed:


dan.hillier.anderson
2020-4-26 21:33:34

@dan.hillier.anderson has joined the channel


dan.hillier.anderson
2020-4-26 21:38:06

anyone able to explain how to write and use a require-transformer?


dan.hillier.anderson
2020-4-26 21:38:47

dan.hillier.anderson
2020-4-26 21:40:08

I’ve got the write done, but figuring out how to properly require an extension for require is boggling my mind


dan.hillier.anderson
2020-4-26 21:42:50

pointer to docs/example appreciated


soegaard2
2020-4-26 21:43:49

Here is a simple example: #lang racket (require racket/require-syntax) (define-require-syntax foo (λ(stx) (syntax/loc stx "bar.rkt"))) (require (foo))


soegaard2
2020-4-26 21:44:41

In the example the syntax-transformer associated with foo simply ignores any arguments and always returns “bar.rkt”,


dan.hillier.anderson
2020-4-26 23:22:07

@soegaard2 I got to about that point. What happens when you want to break the transformer into a separate module?

For example:

#lang racket ;; in ./one.rkt (require (for-syntax "two.rkt")) (require (foo)) #lang racket ;; in ./two.rkt (require racket/require-syntax) (provide foo) (define-require-syntax foo (λ(stx) (syntax/loc stx "bar.rkt")))


michaelmmacleod
2020-4-26 23:29:17

@dan.hillier.anderson in this example, define-require-syntax binds the foo at phase level zero (meaning that you don’t need to use for-syntax to require it from two.rkt. This is a little bit confusing, because the value that foo is bound to exists at phase level one. https://docs.racket-lang.org/reference/syntax-model.html?q=define%2Drequire%2Dsyntax#%28part._transformer-model%29


dan.hillier.anderson
2020-4-26 23:32:10

aha. thanks. I was getting… somewhere just trying to articulate the question. thanks for answer


dan.hillier.anderson
2020-4-26 23:34:18

maybe a good general question is how do I debug phase level problems? this issue was straightforward enough, I understand banging it out with the brain. if it were more complicated (or, if I’m new and need to check my assumptions) how do I poke around during the expansion phase?


dan.hillier.anderson
2020-4-26 23:41:32

one more code dump


dan.hillier.anderson
2020-4-26 23:42:14

(and, it replaces define-require-syntax with make-require-transformer)


dan.hillier.anderson
2020-4-26 23:42:27

#lang racket (require racket/require-transform) (provide foo) (define foo (make-require-transformer (lambda (stx) (syntax-case stx () [(_) (values '() '())]))))


dan.hillier.anderson
2020-4-26 23:42:43

#lang racket (require (for-syntax "two.rkt")) (require (foo))


dan.hillier.anderson
2020-4-26 23:42:48

does not work


dan.hillier.anderson
2020-4-26 23:43:14

but #lang racket (require (for-syntax racket/require-transform)) (provide foo) (define-syntax foo (make-require-transformer (lambda (stx) (syntax-case stx () [(_) (values '() '())]))))


dan.hillier.anderson
2020-4-26 23:43:23

#lang racket (require "two.rkt") (require (foo))


dan.hillier.anderson
2020-4-26 23:43:24

does


dan.hillier.anderson
2020-4-26 23:43:59

my impression was that for-syntax in the first case should just shift up the run level of the imported module; and should be roughly equivalent to the second


michaelmmacleod
2020-4-26 23:44:36

I’m not sure there’s a great answer here. Whenever I have trouble with phases/macro-related problems I use drracket’s macro stepper to look at the phase levels on the syntax objects in my program


dan.hillier.anderson
2020-4-26 23:45:08

:+1: thanks


notjack
2020-4-26 23:46:45

It’s really hard to debug these problems. I think better APIs and best practices would help with that.


dan.hillier.anderson
2020-4-26 23:49:44

is define-syntax eqvlt to begin-for-syntax + define ?


notjack
2020-4-26 23:49:57

unrelated to the above: anyone have any thoughts on this? I don’t understand what it’s asking for but it seems like several people want it https://github.com/racket/racket/issues/2740


notjack
2020-4-26 23:50:13

@dan.hillier.anderson no, define-syntax is not the same as define at one phase higher


dan.hillier.anderson
2020-4-26 23:50:38

goooooood.


notjack
2020-4-26 23:50:44

there is define-for-syntax, which is begin-for-syntax + define


notjack
2020-4-26 23:50:48

but anyway


notjack
2020-4-26 23:51:00

define-syntax is special


dan.hillier.anderson
2020-4-26 23:51:45

appreciated. I decided to jump into the deep end today without re-reading the docs. this what i get.


notjack
2020-4-26 23:52:10

one sec, typing a more full explanation


notjack
2020-4-26 23:54:16

What define-syntax does is it binds something at phase 0, like define, but the right-hand-side-expression is at phase 1. define-syntax is the magic bridge between compile-time and runtime that makes macros work: it lets compile time stuff at phase 1 interact with runtime stuff at phase 0. Without it, the phase system would simply be a fancy way to name different parts of your code: those parts would have no way to interact with each other.


notjack
2020-4-26 23:57:25

In this code: (define-syntax my-macro (lambda (stx) ... do some stuff ....))) (my-macro 1 2 3) We use my-macro in phase 0 code. That’s only possible because define-syntax binds it at phase 0. (This is also why you export macros from a module by writing (provide my-macro) , not (provide (for-syntax my-macro)).) But the thing my-macro is bound to, the (lambda (stx) …) bit, is executed at phase 1 and can only reference phase 1 bindings (such as syntax-parse, if you imported it with (require (for-syntax syntax/parse)) ).


notjack
2020-4-27 00:02:14

define-syntax, quote-syntax, and syntax-local-value together are the three pieces that form the core of a Racket-like macro system. • define-syntax lets you bind a runtime (phase 0) name to a compile-time (phase 1) value • quote-syntax lets a compile-time value refer to a runtime name • syntax-local-value lets a compile-time value get the value of a runtime name, but only if that runtime name is bound with define-syntax to another compile-time value


notjack
2020-4-27 00:03:18

you can make most of the rest of a macro system such as syntax-rules, syntax-case, or syntax-parse out of those pieces - you don’t need to make them built-in to the language


dan.hillier.anderson
2020-4-27 00:08:59

thanks @notjack. that’s a good summary; I was running around with a very mediocre model of syntax/phase levels.


notjack
2020-4-27 00:18:32

@dan.hillier.anderson Here’s a concrete example: #lang racket ;; Bind my-secret at phase 0 to a phase 1 string. (define-syntax my-secret "I am bad at geography.") (begin-for-syntax ;; Now we're in phase 1. We can't refer to my-secret like any other variable, ;; because it's at the wrong phase. But we can quote-syntax it! this lets phase 1 ;; code refer to variables in other phases. ;; quote-syntax produces a *syntax object*. It's like an s-expression, but with ;; metadata about scopes and phases and such. In this case, it produces an ;; *identifier* which is a special type of syntax object that contains only a ;; single name. Identifiers are to syntax objects what symbols are to ;; s-expressions. (define the-secret-identifier (quote-syntax my-secret)) ;; Since we're in phase 1, and my-secret is bound to a phase 1 value, we can ;; extract that value. To do this, pass the syntax object representing the ;; my-secret variable to the syntax-local-value function. (print (syntax-local-value the-secret-identifier))) When the above code is compiled, it will print out the message “I am bad at geography.” At runtime, it prints nothing.


samdphillips
2020-4-27 00:30:33

It sounds like (at minimum) it would change where .racketrc and .racket would be stored (by default) for users. Those locations would also have to be added to any routines looking up those files too.


samdphillips
2020-4-27 00:31:21

Ohhhh


samdphillips
2020-4-27 00:32:04

Actually it should get the locations from the special XDG environment variables and otherwise use the defaults.


notjack
2020-4-27 00:36:49

I’ve never heard of XDG outside of this issue, is it a common standard?


samdphillips
2020-4-27 00:39:21

Linux Desktop standardization. It’s newish (like in the past 10 years-ish)


notjack
2020-4-27 00:55:22

Any idea what other programming languages do for it?


dan.hillier.anderson
2020-4-27 00:57:32

thanks for this. gives me something to chew on.


samdphillips
2020-4-27 01:14:51

No idea. It seems more around tooling. Like if you have a REPL with configuration settings you should go through their env variables to find/put the settings.


rokitna
2020-4-27 01:58:47

No, it’s not quite like that. Usually, when you use define, you’re defining a value that can be referred to in phase 0, and when you use define-syntax, you’re defining a macro (or other transformer binding) that can be used in phase–0 expressions. If you surround these in begin-for-syntax, they define values and macros for use in phase 1 instead.

There does exist a shorthand for the combination of begin-for-syntax and define: define-for-syntax. While it looks a lot like define-syntax, they have distinct roles: define-syntax defines a phase-N syntax, while define-for-syntax defines a phase-(N+1) value for the phase-N syntaxes to use.


notjack
2020-4-27 02:14:09

Happy to help :) if you come up with more questions, please don’t hesitate to ask


samdphillips
2020-4-27 02:18:05

All of the ones in this “Hardcoded” section are essentially workarounded. https://wiki.archlinux.org/index.php/XDG_Base_Directory#Hardcoded


samdphillips
2020-4-27 02:20:40

I’m not yet sold on the usefulness of it… I guess it makes copying dotfiles around easier since all of the configs are in .config


samdphillips
2020-4-27 02:20:53

or whatever you sett the variable to


samdphillips
2020-4-27 02:23:38

> … the XDG Base Directory Specification introduced in 2003.