thybault.alabarbe
2021-4-16 09:17:04

Hi, I am new to Racket and have a couple of questions about what is possible to implement in a #lang, and how I should proceed to implement the following features for my #lang and my ideal Racket development environment:

  1. I want to build a #lang without Garbage Collection with rust’s memory model, is there a way to implement such a #lang in Racket? Maybe someone already did it?
  2. I need a Racket environment running under wasm in a Native Web App, is there a way to compile Racket to wasm and have it generate wasm code? Thanks in advance, a curious but still very new Racketeer

soegaard2
2021-4-16 09:19:37
  1. Do you need “no garbage collection” or just something that behaves the same way?

soegaard2
2021-4-16 09:20:13

(I don’t have any answers - I am just trying to unpack the question)


thybault.alabarbe
2021-4-16 09:27:07

@soegaard2, Ideally I would like a full Racket environment with no GC and rust’s ownership and borrowing methodology instead. That is ideally, in the very long run, because I think it would require a lot of time. But for now, I want to learn how to make a #lang that doesn’t use the GC and handles memory manually. I will then try to make the rust’s ownership system through macros


sorawee
2021-4-16 09:44:59

Racket has GC. You can disable it per instruction at https://docs.racket-lang.org/reference/garbagecollection.html and I think you can use the unsafe API to manage memory yourself. It won’t come with “rust’s ownership and borrowing methodology”.


sorawee
2021-4-16 09:46:00

From the description that you provided, I don’t think Racket would be suitable for your task.


thybault.alabarbe
2021-4-16 09:48:14

Okay, thanks for the feedback, I will look into this documentation. I will probably mostly use Racket as a prototyping tool then :)


phanthero
2021-4-16 10:07:44

How accurate is it to say that Racket (#lang racket, not typed/racket) is a softly typed language? I think what the term “softly typed” is where we can choose whether something is statically typed or dynamically typed? I think Racket is said to be softly typed because of contracts (?), but not entirely sure.


thybault.alabarbe
2021-4-16 10:31:51

Also, I should have started with this one because it is the most important in my case : > <https://racket.slack.com/archives/C06V96CKX/p1618564624039600|2. I need a Racket environment running under wasm in a Native Web App, is there a way to compile Racket to wasm and have it generate wasm code?>


capfredf
2021-4-16 12:49:36

(some-form-a foo) (some-form-b foo) two foo s are free-identifier=. say I have some syntax property on the first foo. How can I access that property through the second foo?


mflatt
2021-4-16 12:53:43

mflatt
2021-4-16 12:54:31

I don’t think there’s any way to do that. Properties are associated with syntax objects, not bindings.


capfredf
2021-4-16 13:00:21

:sadpanda:


samth
2021-4-16 13:25:38

@phanthero I don’t think “softly typed” is a term I’ve heard before. I would say that Racket (meaning #lang racket) is not typed. Contracts are not types.


samth
2021-4-16 13:26:17

@thybault.alabarbe If you want Racket compiled to the web, I recommend looking at racketscript, here: https://github.com/vishesh/racketscript/


samth
2021-4-16 13:27:38

@thybault.alabarbe You could implement a #lang that was like Rust, in that it called malloc and free explicitly under the hood based on where Rust does the same. However, you can’t do what Rust does with stack allocation in Racket. You would of course need to implement the rust type system and borrow checker.


thybault.alabarbe
2021-4-16 13:31:31

Ok yes, I had most of these in mind, but when you say: > you can’t do what Rust does with stack allocation in Racket > do you mean that Racket cannot modify the way it interacts with the stack?


spdegabrielle
2021-4-16 13:32:44

Would the 6502 asssmbler approach used in https://docs.racket-lang.org/asi64/\|https://docs.racket-lang.org/asi64/ be suitable to target another language(wasm)?


samth
2021-4-16 13:33:05

I mean that Racket values, except for fixnums (and flonums in some cases) are always heap-allocated.


thybault.alabarbe
2021-4-16 13:34:00

That’s interesting, I’ll follow the project but the lack of tail call optimization might be a bit of a trouble for performance


samth
2021-4-16 13:34:48

It’s definitely still early for that project, if you are looking to compile real racket applications to javascript we’d be happy to have you contriibute.


thybault.alabarbe
2021-4-16 13:36:30

Ok I think I get it, not even pointers to heap allocated data are stored in the stack frame?


samth
2021-4-16 13:37:24

pointers are stored in the stack frame (or in registers)


samth
2021-4-16 13:37:42

but except for fixnums, all Racket values are pointers to heap-allocated data


thybault.alabarbe
2021-4-16 13:41:17

Sure! I’ll probably build up on some of the tooling. And I think this is my last question since you seem to be involved in the project, do you know if the compiler can itself run in the browser?


samth
2021-4-16 13:41:34

Not yet, but that’s a goal.


thybault.alabarbe
2021-4-16 13:41:52

Alright, thanks!


thybault.alabarbe
2021-4-16 13:42:20

Ok got it, thanks for your help!


capfredf
2021-4-16 14:39:23

I guess @phanthero might be referring to “soft typing”



sschwarzer
2021-4-16 15:30:53

I just ran into some weird behavior (from my perspective in any case). I have this module: #lang racket/base (struct foo (x) #:name Foo #:constructor-name Foo) (define my-foo (Foo 1)) (displayln my-foo) When I run this in DrRacket, I get the output #&lt;foo&gt;, as expected.

Now I add a contract: #lang racket/base ; Only this `require` and the `provide` form are new here. (require racket/contract) (provide (contract-out (struct Foo ([x integer?])))) (struct foo (x) #:name Foo #:constructor-name Foo) (define my-foo (Foo 1)) (displayln my-foo) When I run this, I get: foo: unbound identifier in: foo with the foo in (struct foo (x) highlighted.

In case you wonder, I also tried using foo as the contract name in the provide . When run, this gives me contract-out: expected a struct name in: foo This is what I had expected.

I wonder what’s going on here. Is this a bug? If not, what am I doing wrong? What fix or workaround do you recommend?


samth
2021-4-16 15:40:49

This is a bug in contract-out


sschwarzer
2021-4-16 15:40:53

I experimented a bit more. I get the confusing message only when I use #:name and #:constructor-name together.


sschwarzer
2021-4-16 15:41:56

Is it a known bug, i. e. in the tickets? I didn’t find anything in the ticket system (but I also checked the open bugs so far).


mflatt
2021-4-16 15:41:58

It looks like this is probably a bug in struct where a combination of #:name and #:constructor-name with this same identifier doesn’t work right.


samth
2021-4-16 15:42:08

I don’t think so


samth
2021-4-16 15:42:27

I only recently noticed this while investigating related behavior in Typed Racket with @capfredf


sschwarzer
2021-4-16 15:42:35

Ok, I’ll enter a ticket then.


mflatt
2021-4-16 15:43:20

You probably saw my other reply, but just in case: I think it’s probably a bug in struct instead of contract-out.


sschwarzer
2021-4-16 15:44:09

Yes, I saw your reply. Thanks for reminding me still, so I can add this information (that it’s a bug in struct) to the ticket.


samth
2021-4-16 15:45:15

I think there are some issues in contract-out when you use #:name as well.


sschwarzer
2021-4-16 15:46:22

As a workaround, I can probably get by with leaving out the #:name for now, since I don’t use match with this type and don’t use the type as a super-type. Still, if you have other suggestions for the contract to achieve what the contract should do, I’m listening. :wink:


sschwarzer
2021-4-16 15:51:11

Maybe I should leave out the information where the bug probably is? I suggest you two add this information after further checks.


samth
2021-4-16 15:51:42

I think @mflatt is right about the specific error you got.


sschwarzer
2021-4-16 15:52:27

Ok, thanks!


sschwarzer
2021-4-16 16:00:07

sorawee
2021-4-16 16:02:32

Speaking of this issue, @mflatt, do you remember why did you make a change at https://github.com/racket/racket/commit/096ec546a62b7f36b15ee086c389e59887a0250d?


sorawee
2021-4-16 16:03:21

It causes an issue at https://github.com/racket/racket/issues/3277, but it’s unclear which one between struct-out and contract-out is more “correct”


mflatt
2021-4-16 16:10:20

I added a comment in the issue.


sschwarzer
2021-4-16 20:37:34

I have the following struct definition: (struct progress-data ([records #:auto]) #:auto-value (gvector) #:constructor-name Progress-Data) and the following contract: (provide (contract-out (struct progress-data ([records gvector?])) [add-progress-record! (-&gt; progress-data? integer? integer? integer? any)] )) In this module, I can use (Progress-Data), as expected due to the #:auto field.

When I import the above module into another module and there invoke (Progress-Data) , I get an arity mismatch error (expected: 1, given: 0). This corresponds to the contract, but not the struct definition. On the other hand, if I delete the field from the contract, i. e. (provide (contract-out (struct progress-data ()) [add-progress-record! (-&gt; progress-data? integer? integer? integer? any)] )) Racket gives me an error contract-out: found 1 field in struct, but 0 contracts How does the contract have to look like to allow using (Progress-Data) in the importing module?


kellysmith12.21
2021-4-16 20:54:40

@capfredf Instead of putting a syntax property on the identifier, what you can do is (define-syntax foo &lt;data you want&gt;) then, you can retrieve the data with (syntax-local-value #'foo) in a macro.


alexharsanyi
2021-4-16 22:46:05

Hi @soegaard2, I made another attempt at fixing this, on the “ah/macos” branch, can you please try it out?

https://github.com/alex-hhh/gui-widget-mixins/tree/ah/macos


philip.mcgrath
2021-4-16 23:20:54

@sschwarzer This looks to me like a bug in either contract-out, or struct, possibly related to the relatively recent changes. But #:auto-value is rarely a good idea: in this case it would create a single mutable gvector shared by all Progress-Data instances.


samth
2021-4-16 23:55:09

Yes, I think #:auto fields are not supported correctly by contract-out; it would need you to provide #:auto in the contract-out spec


sschwarzer
2021-4-17 06:24:36

Ouch, I don’t want a shared vector. I thought this would be evaluated for each struct instance. And I even wouldn’t have noticed because for the time being, I’ll probably need only one Progress-Data instance.


sschwarzer
2021-4-17 06:25:38

So I guess I should go with a “constructor function” like make-progress-data instead that creates a Progress-Data with an empty gvector?