
@thegobinath There’s none yet, but I’m working on it: https://github.com/euhmeuh/web-galaxy On the other hand, a static site generator like https://github.com/greghendershott/frog is getting popular, but it’s not a “web framework” per se.

I feel like it’s so simple to make your own from the basic racket/web-server package that everyone makes its own brew.

But as a beginner, I felt a bit lost because it doesn’t look like a classic web server the first time you try it. There’s all those strange concepts of continuations and all… Then you get to understand that continuations are not really necessary, and you start making your own wrapper around the server.

With web-galaxy, I want to provide an easy access to that technology, without the fuss and the complexity of having to read the documentation line-by-line in the right order

In the end, one usually just wants to define some routes and serve them, keeping the complexity for later

Then I want to add support for javascript modules and web components

So that you can write javascript as racket (using the urlang package) and generate your full web application from that

Maybe I won’t have time to do all that in my spare time, but if I can inspire others to try something like that, and create traction, that’d be good enough.

Ok. Will try it out.

@jerome.martin.dev curious, what are your ideas for html dsl, I remember your talk at fosdem https://github.com/euhmeuh/fosdem-2019-talk/blob/master/slides.pdf are you still planning on something similar to page 34?

Yep!

A DSL that would permit to describe the HTML template, the javascript, the database fetching…etc all in one part of the code

that would be my dream come true :slightly_smiling_face:

one thing I always found annoying about xexp is the nesting of the attributes

what I personally like is the approach of laml

are you aware of that old library?

I have become fond of the at-expression syntax. Example: https://github.com/soegaard/urlang/blob/master/urlang-examples/parabola/parabola.rkt#L118

at-expr is one neat approach

Note that the above doesn’t build an s-expression, but represents the html using structs.

The at-expr approach is nice, but I feel like there’s a bit too much @
x) Joke aside, I’m not fixed on the notation yet, but I guess I want to make it as transparent as possible

Yeah - It’s tricky to find a good balance.

The more text (non-html) you need the better it gets.

in laml (div ([class "pony"]) (pony-name the-pony))
becomes (div 'class "pony" (pony-name the-pony))

which is also something I like

laml is great yeah, I had something like that in mind

What I really want to promote is the “duality of syntax” that Doug Hoyte writes about in Let Over Lambda

make it so that there’s no difference between writing code and writing template, and that both can be intertwined seamlessly

especially now with web components it seems even more doable

yep

I’ve been waiting for web components to finally be implemented by every browser for a long time now. But some times ago a colleague shared the link to an article explaining how a big banking company used web components for all the website, and only had a polyfill for Internet Explorer, making it possible to actually use web components in production for every browser. And I was like “OK, now’s the time!”

How do you see web-galaxy working with the multiplicity of Javascript MV* frameworks (current and future)

I guess it could be agnostic. But I’m really trying to push forward vanilla JS, because with ES6 + web components and shadow DOM, a lot of those frameworks have superfluous parts.

Especially since Racket works exactly as Babel for Javascript : it makes a perfect transpiler through macros.

My challenge is to try using only standard browser features instead of writing an MVC framework

I don’t know if that’s possible, but I wanna try and find out were it goes

that would be ideal but seems like a challenge

so far every time I wanted to write a web app entirely in Racket after some time I had to move into pure Javascript as it was getting more and more complex to keep it in both worlds

So in essence you are thinking more about svelte approach?

I’m striving for minimalism :slightly_smiling_face:

but with Racket as transpiler

Yep, pretty much something like that

great to hear all that, and fingers crossed (as that would be brilliant)!

I’m glad to hear that :smile: Let’s just hope I have enough brain-time for all that :stuck_out_tongue: When I have a full working proof of concept, I’d be glad to share it here.

brain-time is an excellent combination - why is that that we either have enough brain and not enough time or enough time and not enough brain? :grin:

I so agree with that :stuck_out_tongue:

@mflatt So, after looking at mred/private/wx/common/event
, it looks like it’d be fairly simple to breate events into something like racket/event
.

If so, would it make sense to move events to the main racket repo (and have the gui-lib one reprovide them), or would it make more sense to add a new package to the distrobution, or something else?

Or, I guess, it’d also be possible to make a racket/gui/event
collection, and just document that that collection can be instantiated multiple times unlike racket/gui/base
.

Yes, racket/gui/event
within gui-lib
sounds like the right idea for now.

Alright, I’ll prepare a PR, thanks.

@jbclements @samth winooski seems downski again?

@jerome.martin.dev regarding html syntax, what do you think of using keyword arguments for attributes? (div #:class "pony" (pony-name the-pony))

Yep, using keyword arguments is definitely the most “racketty” to me

I think I’m gonna go with that

nice, then they can be normal functions too

@greg right you are, and for exactly the same reason. I believe Stephen Chang is working on bringing it back up. Perhaps this time I won’t crash it again.

What are you running on winooski, some kind of Elizabeth Barrett Browning AI to compute all possible ways to express HTML using Racket? :smile:

just trying to run the branch build, sigh.

I’m sorry. It sounds frustrating and my bad humor is probably not helping.

on the contrary! A little gallows humor is always appreciated! :slightly_smiling_face:

@jbclements Has branch day happened? From GitHub, it looks like the answer is “yes”, but I want to make sure. I’m trying to figure out if it’s safe for me to merge something to master without it ending up in v7.3.

@lexi.lambda yes, the catalog is built, the release branch exists, and master is now on 7.3.0.1. so merges to master should not wind up in the release by default.

Great, thank you!

@mflatt Actually, looking at it a bit more, it looks like (afaict anyway) ‘most’ of mred/private/wx/common
can be instantiated more than once.

(Except for stuff like queue.rkt, which I think is because of the use of atomic mode?

Hey everyone. I’m still getting into Racket, but I love it so far. In my search for information as to whether Racket supports persistent data structures [1] I came across this article [2] from 2010. I was wondering how many of the Racket criticisms in the article still held true. Don’t get me wrong: I’m definitely on Team Racket. :slightly_smiling_face: I’m just curious as to how Racket may have changed since the article was written.
But going back to my initial quest, does Racket support any sort of persistent data structure, one that preserves the previous version of itself when it is modified?
I guess that’s two questions, but perhaps in answering the first, the second may be answered as a side-effect.
[1] <https://en.wikipedia.org/wiki/Persistent_data_structure>
[2] <https://programming-puzzler.blogspot.com/2010/08/racket-vs-clojure.html>

as to the persistence there are some packages: https://pkgd.racket-lang.org/pkgn/search?q=persistent

Oh, thank you @githree! The problem with being new to a space is not even knowing where to look for answers. I appreciate the link.

@daniel there are lots of persistent data structures in Racket.

it’s still true that by default, Racket come with a few built-in data strucutures, and only one of the default ones is a sophisticated modern persistent data structure (functional hashes)

Thanks, @samth. I’ll look into functional hashes. Great information,

it’s also worthwhile to use github language:racket for finding some interesting code: https://github.com/search?q=language%3Aracket+persistent


@daniel As Sam already said, Racket’s immutable hash datatype is a HAMT, which is the same way Clojure implements its maps. In addition to that, I implemented Clojure’s persistent vector data structure in Racket as the pvector
package, here: https://docs.racket-lang.org/pvector/index.html And there are other persistent data structures available in various packages, too.

This is all great information. I rarely get excited about a language (I’ve been doing this for longer than most of you have been alive :slightly_smiling_face:) but I must admit, Racket’s really taking hold of my brain. I have a lot to learn here, but to paraphrase Tank from The Matrix, it’s a very exciting time! Thanks again, everyone.

is flattered to be considered young

@lexi.lambda thanks for your email on racket-dev. Currently trying to get kids in bed. I have a solution to the problem, which have been lazily delaying implementing it. Thanks for the nudge. Will get done tomorrow morning - i.e. in the next 12 hours. Will reply to the mailing list as well explaining the mitigation and future plans.

No worries, it isn’t a big deal!

FYI, in racket-on-chez, the immutable hash is a patricia trie

@jaz oh interesting. I thought it was still a HAMT

We tried (er, no pun intended) both (and a HAMT is still in the repo, I believe). The HAMT does have better memory usage but it’s slower on most operations.

My best guess is that this is because creating a new HAMT node involves creating a new vector (which also has to zero out the memory) and then vector-set!
-ing the whole thing. So, each slot is written to twice, and each write has to go through a GC write barrier. But this is really just a guess.

I don’t think the zeroing would trigger the write barrier, but that’s all very interesting

No, you’re right. Only the second write goes through the barrier.

BTW, one of my reasons for suspecting vector writes as the culprit is that a version of the HAMT that stores a cons cell (containing the name/value pair) in each slot performed better than one that uses a flat vector twice the size.

Apropos, did Chez get immutable cons cells?

I don’t think so

racket immutable conses are just chez mutable conses

ok

It seems like mirror
is tougher to fix today than yesterday. :disappointed:

My own bad luck these two days I had a chunk of time to do/push many commits, and Travis CI decided to CRON build Frog.

Many things prevent multiple instantiation. Some of it is that global hooks are installed or global classes (for Objective-C) defined. Some of it is that GUI toolkits do not support running in multiple OS threads.

Can I ask which service it is that you’re depending on here? Is it the catalog?

Sorry should have said @greg on that previous message

@greg … no, catalog seems to be intact. Is it just the main racket download?

@a.pelenitsyn has joined the channel

in NEU PRL, http://mirror.racket-lang.org\|mirror.racket-lang.org is currently used to download Racket inside Travis, and we can’t get to it today

@jbclements https://mirror.racket-lang.org/installers/7.2/racket-7.2-x86_64-linux.sh isn’t connecting, and that is the main/default download link (also used by stuff like Travis CI tests)

(but also by humans who want to download Racket)

@a.pelenitsyn yep, working on it…

Thanks. Don’t mean to nag, just want to make sure you know it’s down now. (Like, yesterday it was fixed in a few hours, so, it seems plausible it might have been fixed today, but went back down again w/o anyone noticing yet.)

For now, we’ve made the default download link point to the Utah mirror. That doesn’t help with Travis CI configurations, though.

@mflatt OK, I did similar.

I was trying to calculate an element-wise sum of a nested list and bumped up against a gap in my (very limited) understanding. Here is a simple example: > (define x '((1 2 3) (4 5 6) (7 8 9)))
> (apply map list x)
'((1 4 7) (2 5 8) (3 6 9))
> (apply map + (apply map list x))
'(6 15 24)
The first results was as I expected. But I thought that I could then pass that new nested list to a similar (apply map)
structure and get '(12 15 18)
. Is there a simple explanation for what is happening here? Or can someone point me to the relevant section in the docs? Thanks.

@travis.hinkelman (map f as bs cs)
ends up producing (list (f a_1 b_1 c1_) (f a_2 b_2 c_2) ... (f a_n b_n c_n))
. (apply map list x)
therefore performs (map list (list 1 2 3) (list 4 5 6) (list 7 8 9))
, producing (list (list 1 4 7) (list 2 5 8) (list 3 6 9))
. Now, you pass that value to (apply map + ....)
, leading to the function call (map + (list 1 4 7) (list 2 5 8) (list 3 6 9))
, which produces (list (+ 1 2 3) (+ 4 5 6) (+ 7 8 9))
, just as before, which eventually reduces to (list 6 15 24)
.

Put another way, (apply map f lsts)
“zips” up the lists in lsts
using f
, so the nth element of the result list becomes the result of applying f
to the nth element of each argument lists.

As it happens, this works out to mean (apply map list lsts)
“transposes” lsts
, so that if you view it as a two-dimensional list, it flips the axes.

Anyway, if you wanted to get (list 12 15 18)
, then you don’t want to transpose the original x
value at all: you just want to call (apply map + x)
, which does the “zipping” along the appropriate axis, leading to (list (+ 1 4 7) (+ 2 5 8) (+ 3 6 9))
. Or, if you wanted to turn the transposed list into (list 12 15 18)
directly, you could write (map (lambda (lst) (apply + lst)) (apply map list x))
, which would produce the same result.