[ art / civ / cult / cyb / diy / drg / feels / layer / lit / λ / q / r / sci / sec / tech / w / zzz ] archive provided by lainchan.jp

lainchan archive - /λ/ - 17588

File: 1469627286925.png (46.17 KB, 300x300, plt_scheme_lisp_logo_steal-your-face.png)


Hey fellow lainons, let us a talk a bit about Racket in particular.

I am pretty surprised that this tasty Scheme flavor isn't more popular:

- Actively maintained by skilled people
- Goes well with SICP & the 'Schemer' series (has #lang's for both)
- Because of that it is a nice Lisp to satisfy our scientific lambda urges
- Nice DSL properties, even used by Naughty Dog because of that
- Nice Documentation
- Pretty useful (in a practical sense) standard library

It seems to me like this language is unable to shake off its "Teaching Language"

What do you think about Racket?


I think it looks amazing and want to learn it, but haven't started yet. HtDP looks better than SICP.


File: 1469645789500.png (25.38 KB, 200x176, sicp_cover2.jpg)


> HtdP

I don't think it's really in rivalry with SICP, since it covers more entry level programming while SICP provides a really nice (and more academical) start into Computer Schience.

So why not both? :)


Traditionally I've been more of a CL guy, but Racket looks really, really good.
I don't quite like HtDP, I skimmed it and... no.
But the language does look promising.


File: 1469647609961.png (59.63 KB, 200x158, not-spam.png)

Other nice features:
>module-oriented language makes it easy to create and pass around libraries that play nice with each other, like typed & untyped code, first class modules and sub-modules allow you to cleanly separate "main" procedures that just run everything and the actual library, or testing units of code with their own data and procedures.
>lang feature allows you to nicely separate reader-macros from one another
>package management (still an ongoing problem with Scheme, only "recently" solved in Common Lisp with Quick lisp)
>algebraic data types
>abstraction over GUI allows you to "write-once-compile-anywhere" without worrying about having to deal with a less-than-native GUI interface or having to learn a new GUI system
>excellent OOP support as well if you need it
>declarative, logic programming

Part of my post was marked as spam.


Would it be safe to say that racket is the best introductory language to functional programming?


That depends on how you learn/use it.

Racket itself is multi-paradigm.


I used to teach Racket at a university. It's pretty amazing. Don't know why it's seen as a toy language, but it's a great way to learn lisp / scheme.


Is there a tool to create standalone executable of racket program for win/linux/mac? Maybe lack of it hinders adoption?


You can do that easily with `raco exe <file>`, raco comes with the standard Racket distribution.


File: 1469751065416.png (200.12 KB, 200x75, gdmoogi1412135943592.jpg)

guile[scheme] master race
though most any lisp is gonna be cool

original lisp is the sensei
maclisp is the meek megane class rep
common lisp is the popular gyaru cow
scheme is the beautiful blonde loli
guile is her weird goth twin
elisp is this unimaginable hikikomori ojyousan hybrid
closure is the dumb genki girl
ratchet is the sporty bokugirl in spats

only here because of your pic
always nice to find deadheads that share some of your other interest
if you're also a free software advocate and vegan we should maybe just get married


I would pay to watch a Lisp anime


File: 1469768562091.png (56 KB, 134x200, cl-chan.jpg)


Someone should create Racket-chan artwork.
Unfortunately, I'm not able to draw, at all :(


File: 1469773008575.png (38.41 KB, 200x113, racketchan.png)

Here's the trash you ordered


File: 1469834640244.png (165.36 KB, 200x200, drracket1.jpg)


It seems Carmack has been using it a lot at Facebook/Oculus for prototypes and even thinking of using it as a way to have a live VR environment to create simple VR experiences.


Can anybody recommend some good sources/reads/books on creating DSLs (using Racket)?


Programming Languages: Application and Interpretation and Semantics Engineering With PLT Redex.

I've heard the latter is a pretty good but dense book, it's written by the same people behind Racket and The * Schemer series. Redex is a Racket-embedded DSL for specifying and implementing formal grammars while also interactively exploring them.


That motherfucking diversity poster in the background


I think some guy on 8chan was working on a SICP VN.


I think one of the underappreciated parts of Racket is the distinction between Racket, the language, and Racket, the language development platform. It's very, very nice for that. For example, where Common Lisp's macros are more imperative and require you to manually gensym and destructure s-expressions, Racket declarative pattern matching macros, where you can define your own syntax-classes and syntax-patterns, and where syntax objects are aware of scope, via syntax-parse. It's just a damn nice setup, and you can tell a lot of work went into making it state-of-the-art.


> and you can tell a lot of work went into making it state-of-the-art

Like many parts of Racket as a whole, the thing that amazed me: I wanted to write a small IRC Bot and managed to get the basics running after a few hours, I have never worked with Racket before that, the Documentation is great and it comes with so many useful practical libraries, this becomes even more remarkable if you think about how "few" people actually use it.

Racket seems to me like Python done right, and as a lisp.



I only wish they would focus just a little bit less on DrRacket, it is a nice tool (I love the built in debugger), but for actually editing more than a few lines I prefer other editors.


Really? I was thinking recently that I wish they focused on it more, since I also prefer other editors. It's paredit mode is kind of lacking since it can't automatically delete closing parens, only insert them. The autocomplete it comes with only works for the standard library stuff, and won't autocomplete your own definitions in that module or in imported modules. There's small things, but they become tedious pressure points over time compared to emacs.

On the other hand, its debugging and stepper tools are excellent and aren't present in emacs at all, and some features aren't (sometimes can't) really be in emacs (displayed images as first-class values! in-scope automatic renaming! graphical profiling! macro-expansion and debugging! etc.). It would really be a killer editor if it had just a little bit more tweaking for things that emacs has but it doesn't. As it is, it's great for debugging and for people who don't want to bother with emacs, but it's just not quite as nice for longer-term editing as emacs is for me. Still, a get-up-and-go editor packaged with the language itself and developed alongside it was a great idea. It really reduces a lot of friction to learning a language when you have to set up a complex separate general IDE/editor for it.


Oh right, since I'm on the topic and have a list I wrote down of some pressure points I'll list them here (even though I should really bring them up on the mailing list or try to implement them myself, whoops):
- Integrated git a la magit
- auto-delete parens
- insert lambda symbol without menu-keybindings on (minor quibble)
- Treat block comments as parens for paredit-like manipulation
- Automatically wrap text when it passes max column width
These are pretty minor points for me, but they kind of grind on me over time and stop drracket from being my "preferred" editor for Racket. Nothing wrong with emacs being that editor though.


Didn't Racketcon just start up? Some highlights:
>Rosette program synthesis and verification
>JPEG parsing in DrRacket
>generative art
>type systems as macros
>weather systems


wait weather systems?


racket is really nice, but it's not really a scheme anymore. idk what to call it.


Are there any known projects that use racket?
It seems like an excellent fuarrrking language, its clear that so much time and effort went into build the standard library.


The Senior Software Developer at AccuWeather uses Racket to decode, parse, query, interact, transform, and share data from binary and compressed files used for weather services that were formalized during ye olde Fortran years in real-time using a DSL.


RacketCon and the mailing list are a really great way to see what's going on in the language community and what people are using it for.

shows the current convention, and has links at the bottom for previous years.


There's a lot to love about Racket! I like that it has static typing that plays nice with Lisp and with non-typed programs. I also like its contract system, as I feel it formalizes what interpreted languages tend to already do. I think that there's a lot of potential in its language building platform, and that it proves it through its wide range of practical langs (eg typed, different Scheme varieties, scribble, Arc (which runs Hacker News, love it or hate it), soykaf it even has ALGOL). I find it very comfy to write in with amazing documentation, a good help system, a nice and simple test framework, and (good and fun) batteries built in. I don't use DrRacket (hooked on Emacs) but I think it's neat and a good example of a practical program written in the language. Its macros are more advanced than any Lisp too, and currently a rewrite of its compiler is in the works so it'll be bootstrapped (IIRC).

Some things could be nicer, and there's some weird hold overs from Scheme. In general I wish less of the built in data structures were mutable, especially strings. I'd like to see Racket use immutable mappings and other functional programming data structures. Of course, there's nothing stopping me from using them as they have been implemented in the language, but at the moment it feels like using the mutable structures is still encouraged. Making a pure wrapper language feels silly but I might do it someday, just to see what I can write in it.


a big problem i have with racket is the lack of a scanf alike procedure. how something this useful can be missing? this is why academic PLs are doomed to fail.


File: 1477411678808.png (45.07 KB, 200x150, 1476946515688.jpg)

Are you being serious?


Maybe he's joking.


Yes, i am. How, in racket, do you quickly read a text input and convert that text into another data type?


File: 1477420134339.png (364.96 KB, 160x200, lain18.png)

You write a function for that? I really don't know what you are getting at


I had the same question in trying to get some such input, of course the answer is >>19649 but it wouldn't be a simple procedure, it's more of a convenience function that a language would come packaged with (a language that'd claim to be featureful anyway)


otherwise you can do something like
(parse (append "(" (read-line) ")"))
(note that I don't know what the 'parse' function is in actual Racket)


C'mon you guys, just look in the docs, they're extremely comprehensive.


We have (read) which reads from (current-input-port), and outputs an s-expr. There's (read-line) which reads a line from a port and returns a string, which you can convert to other data types like so:
(define (read-number)
(string->number (read-line)))
(define (read-symbol)
(string->symbol (read-line)))

If you have a string that you want to convert into an s-expr, you have to read from a "string port"
(define (parse str)
(read (open-input-string str)))

Racket has a really neat dynamic scoping system called "parameters". If we look at the definition of (current-input-port) or (current-output-port) we see that they are "parameters":

Here's how parameters work:
(define my-param (make-parameter 'x))
(printf "before: ~a\n" (my-param)) ; -> x
(parametrize ([my-param 'y])
(printf "inside: ~a\n" (my-param))) ; -> y
(printf "after: ~a\n" (my-param)) ; -> x
We can parameterize current-input/output-port to use whatever ports we like.
See this interesting example:

; a stupid game demonstrating IO
(define (the-game answer)
(printf "Guess a number: ")
(let ([user-inp (string->number (read-line))])
(if (= user-inp answer)
(printf "Correct!\n")
(printf "Incorrect :(\n")))

; play the game using stdin/stdout (default)
(the-game 5)

; play the game over a TCP connection
(let ([server (tcp-listen 12345)])
; accept a client
(let-values ([(in out) (tcp-accept server)])
(parameterize ([current-input-port in]
[current-output-port out])
; play the game using connection's ports
(the-game 6)))
; bye
(tcp-close server))


>The solution is to re-implement scanf by yourself

lel, thanks for proving my point.

Read this post from the racket forum



my problem was with input lines such as
>1 1 2 3
and more generally
>"a string" 1 2 (a list)
I realize a scanf-like would be stateful, however, but what I did at >>19651 would >just work
Here it is, rewritten to actually work in Racket
(read (open-input-string (string-append "(" (read-line) ")")))
which would just return a list of Racket objects as read from stdin.
Problem with just (read), at least in my repl, is that it reads up to a space (unless between quotes or parentheses) and each time, not always desirable


When you have very specific input format youre gonna have to expect to write a specific reader. Racket has a lot of features but unfortunately brevity is rarely their concern. E.g.
All do the right thing but they have pretty gigantic names. If you want to just write code really fast I guess go ahead and use Python. Or atleast write condenced versions of common reading functions and reuse those.

As for formatted input ala scanf(), it would be really nice if racket had that but I think they prefer you use regex instead, which is almost always more appropriate for non-trivial applications.

Also I think the appropriate solution to your space delimited s-exprs is (in-port)
(let* ([s "1 2 (a b) 3"]
[in (open-input-string)])
(for ([dat (in-port read in)])
(printf "read: ~v\n" dat)))
You could use for/list or sequence->list if you want the datum as a list.


That's an interesting discussion, and I think I would be wary of using racket in a programming competition, but I found myself agreeing with a lot of the points AGAINST the use of scanf... it is kind of a dirty tool that works for super simplistic input but is not very powerful at all...


The problem is not really about verbosity but more about complexity and tediousness.

something like scanf but on regex groups?

(regexp-group-format #rx"\\[(.+), (.+), (.+)\\]" "[1, 2.0, abc]" "%d%f%s")

would evaluate to

'(1 2.0 "abc")


>complexity and tediousness
Writing code that parses delimited complex expressions from an input would be insanely complex in C, or Python, or Java...
(for ([datum (in-port read in)])
Is not complex or tedious.
(string->number (read-line))
Is not complex, and is only made tedious by its verbosity.

The C code for reading two integers from a file seems easy, fscanf(f, "%d %d\n", &a, &b), but is really not powerful, and implemented through quite a lot of hacks. What if you wanted to read an arbitrary number of integers? Talk about complex and tedious...
The racket solution for two integers is definitely much more verbose, but can be quickly extended for more complicated inputs, and youll end up with code that is atleast very clear to understand.
(define (split-numbers line)
(map string-number (string-split line)))

(match (split-numbers (read-line))
[(list (? integer? a) (? integer? b))
<handle two>]
[(list (? integer? nums) ...)
<handle any>]
[_ (error "bad input!")])

Note that the Python solution would be much more concise but (arguably) less powerful.
nums = [int(w) for w in input().split()]
# throws ValueError on malformed integers
if len(nums) == 2:
a,b = nums
<handle 2<
<handle any>

In the end it comes down to what you want. If all you care about is short code, use Python to your hearts content. If for some reason you are in love with scanf(), be my guest. But I firmly believe that Racket is a very powerful and well designed lisp, at the expense of verbosity.


As long as we're considering alternative abstractions, a macro that collects the bound groups to a list, then reads from each string seems useful here, and pretty flexible, at the expense of speed. Something like:

(regexp-group-read #rx"\\[(.+), (.+), (.+)\\]" "[1, foo, 0.42]") => (1 foo 0.42)

If you're going to go with scanf type specifiers for easier regex construction, speed, and safety, it would be better to define those in terms of regex strings themselves, and then splice back into the main regex. This makes it harder to give useful errors on type mismatch, but still safer than the alternative.

(regex-scan #rx"\\[%d, %s, %f\\]" "[1, foo, 0.42]") => (1, foo, 0.42)

That might be a little overkill, though.

Sorry if some of the stuff or the macro names doesn't make sense, I don't work with scheme much.


Well, we could create an entire sub-language for scanf-like-formats that can be parsed somewhat safely; format strings are essentially sub-languages, but they are very simple, and thus can only parse simple data. And C is only good at working with very simple data. If we wanted to allow for more complex data, then the complexity of our format string sub-language would increase.
This is one interesting case where typing systems like Haskell really come into play, because we could create a very simple format string language, as the data parsing rules would be delegated to the type system.
e.g. scanf "[%1, %2, %3]" :: (Read a, Read b, Read c) => String -> (a,b,c)
This isn't really possible in languages without sufficiently powerful static type inference.


>but is really not powerful
scanf is powerful enough for most stuffs.

Also, scanf can receive a format string from the dynamic environment.
eg: https://ideone.com/Wfif14

>implemented through quite a lot of hacks
scanf isn't relying on hacks at all but on well specified language semantics.


Not a huge fan of Racket myself. It does have some really, really, cool ideas and features, and there's nothing actually wrong with it, I just don't really like it.

My Lisp of choice is CHICKEN Scheme (I tend to prefer Schemes as a rule, as opposed to Racket, CL, and Clojure, the other big three dialects): It's got a small stdlib, but a fairly decent set of libraries for a scheme, and an excellent community. It's got a nicely practical focus, and IMHO, it's one of the best schemes for getting stuff done.

I suppose I just enjoy the more minimalist Lisps, as it's easier to wrap your brain around the tools they provide. Maybe if I was actually in the industry, I'd lean the other way, as the larger lisps admittedly do a lot of work for you.


>It's got a nicely practical focus, and IMHO, it's one of the best schemes for getting stuff done.
JazzScheme is another full Scheme programming environment

Seems to be still active

>I suppose I just enjoy the more minimalist Lisps

chicken scheme is not minimal, it's bigger than racket/base.

Minimal Lisps are

husk scheme


Jazz looks neat. It's always good to see things built on Gambit, and it looks like a decent environment. The one problem with Gambit tooling is that there isn't much of a broad ecosystem, at least not to the same degree as there is with Chicken, which is a lot easier to find libraries for.

>chicken scheme is not minimal, it's bigger than racket/base.

But far more minimal than #lang racket. It's also less conceptually crowded than Racket, which counts for a lot, IMO: The more concepts you have to get your head around, the less brainpower you have left over to focus on your problem. Your tools should thus be as simple as possible, so that you can understand them well.

Picolisp is probably THE most minimal lisp you can really get stuff done it, and another favorite. Husk is too minimal to use for doing large-scale Real Work, although neat enough, and probably good for embedding in your haskell code. Femto is interesting, but it's not really well documented enough for me to get into it. Pixie looks neat: however, I've never seen it before, so it requires further exploration before I can judge much about it.


>The more concepts you have to get your head around, the less brainpower you have left over to focus on your problem. Your tools should thus be as simple as possible, so that you can understand them well.
this may be the reason I don't play along too well with big languages.


New Racket version out! Current version is 6.7, and includes things like:
>more interactive REPL via xrepl and racket/interactive with line-editing, command, result history
>authenticating packages installed via git
>more Typed libraries, racket/OS and racket/db/SQLite
>more bytecode optimizations for struct, string, bytestring, and list operations

And this too:
>Racket now supports building graphical applications on Android


>Racket now supports building graphical applications on Android

Neato, this might be fun to play around with.


File: 1477841095268.png (138.14 KB, 183x200, jWWPolf.jpg)

what's the best way to represent a 2d buffer in racket?

currently, i am doing

#lang racket

(require math/array)

(define width 64)
(define height 64)

(define buffer (array->mutable-array (make-array #(64 64) #\*)))

(define (buffer-display)
(for ([row (in-array-axis buffer)])
(for ([char (in-array row)])
(display char))

(define (buffer-set! x y v)
(array-set! buffer (vector x y) v))


are there any racket packages that you guys use?


>Racket now supports building graphical applications on Android
If Racket was available as a program to install on Android that would be great



HtDP is more like an algebra textbook than an introduction to computer science.


File: 1477952368273.png (19.13 KB, 200x61, racket.png)

what the hell is this syntax?
>computes an approximation of the probability of the half-open interval (1/2,1]
I have never seen this in any other example.


There's a whole language of families called Lisps that have existed since the 1950s that all have syntax like this.


As in, install it and then boot up a REPL from an Android device? IIRC there was a discussion in the mailing list where this was attempted and "sort of worked" (i.e., it would finish compiling and you could run a REPL, but not do much else). There wasn't any progress beyond that because, well, why would you do any development work on an Android phone/tablet?


it sucks that I can't find where in the reference they talk about it since there is no link in it, only the operator < or > but any example of their use is in the regular form (< this that)


cheers mate



I'm pretty interested in Butterick's Pollen typography system. It seems like there's no other competition to what LaTeX/TeX provides, and doing anything beyond filling out shit like resume templates in LaTeX quickly becomes a pain in the ass. I'd much rather deal with Racket/Lisp as a scripting language for typesetting than TeX, sorry Knuth.


Pollen is partially based on Scribble, the official doc format of Racket: http://docs.racket-lang.org/scribble/index.html


Yes, I know what it is. That's why I'm interested in it.

Since Scribble's been brought up I've had a question kicking around in my head for a while:
Can Scribble output to Markdown? I don't mean output a rendered .pdf /via/ Markdown (I know Markdown is one of the Scribble backends you can choose), I just mean "plaintext" with Markdown formatting. I haven't been able to find anything in the docs about doing this and it would be a tremendous help. I'd be able to write my program in a literate style, and then output both "standard" Racket-style documentation and GitHub-renderable readme.md's at the same time.


You're in luck, there's a guy reimplementing the TeX algorithms in Clojure.


Lains, could you recommend some good resources for learning racket, given that I have very little knowledge about programming? Could be a book or online tutorial.


Much appreciated! Now all I need is time and patience.


You should also definitely read the little schemer.


Eh. Having read it, I can say that if you have a firm grasp on recursion already, it's not really worth your time. Go read one of the other suggested books. Or go read The Lambda Papers. Or read Recursive Functions of Symbolic Expressions And Their Computation By Machine, Part I.

Neither of those last two will help you learn Racket, especially, but they'll help you as much as The Little Schemer would, and you're likely to get more out of them.

Unless you don't have a good grasp on recursion, in which case disregard all that, and go read The Little Schemer right now.



that whole website is strange. Usually language A is faster on the first two cases, and then the language B is faster on the rest of the cases.
Are the first two something like a niche where most language implementations that optimize for the average case usage don't care about?


results are sorted faster to slower.


oh that explains it... my bad
anyway I was looking at some implementations of common lisp programs and it's natural that it gets bad results like in the pidigits one where the top implementations use a bignum library and the CL implementation doesn't.
I think it would be good if experienced Lispers would submit better implementations of those programs


>Racket 0.20 secs
>node.js Bad Output
lmao what?


File: 1478269596087.png (69.97 KB, 200x118, l.png)

>Racket 0.20 secs
probably a bug in the website, see pic
>node.js Bad Output
probably a bug in the program


What's wrong with a poster in the background, I mean I understand you might not like PC culture, but it's a sign on a wall


File: 1478289805421.png (17.72 KB, 200x199, wat.jpg)

any expert to explain why spectral-norm on racket is 2x slower than on node.js despite the first being parallelized while the second isn't? what kind of madness is this?



>any expert to explain why spectral-norm on racket is 2x slower than on node.js despite the first being parallelized while the second isn't? what kind of madness is this?
The event loop in node is implemented in C++, not JS. Pretty much all the I/O in node is implemented in C++ also




I believe JIT engine is not main selling point of racket while node.js uses V8.

Would be interesting to compare native code they ended up in runtime.


so? C isn't some kind of "go-fast" juice you can just slap onto a project to make it speedy. It's just a portable low-level language.

Node.js is a single-threaded environment intended for creating performant high-workload webservers with non-blocking IO. Many of the language developers are working very hard to make it perform its task very, very well.

Racket Lisp is a general-purpose high-level language intended for exploratory programming and platform for DSLs and language development. Many of the language developers are working very hard to make it perform its task very, very well.

The two languages have two very different tasks its developers keep in mind when working on making their language better.


racket's jit implementation is a joke compared with node.


then, if they are incompetent, why not use an already available backend programmed by more skilled people? like llvm or v8 or luajit or mono or ...


File: 1478355996518.png (40.4 KB, 200x150, 1400857966432.jpg)


source secs KB cpu load
--------- ----- ------ ----------------
Lisp SBCL 4.08 29,932 98% 97% 98% 98%
Clojure 5.23 63,380 85% 87% 86% 95%
Node.js 15.78 27,160 1% 1% 0% 100%
Dart 15.89 48,720 1% 1% 1% 99%
Erlang 18.00 35,760 98% 98% 98% 98%
Racket 27.29 30,716 58% 49% 41% 55%

>beat by two non parallel versions
>only use ~55% of each processors

wtf, how can you even defend this? Racket performances are plain bad.
How good racket is for parallel and distributed programming?


They do. I kind of have the feeling that you have no real interest or knowledge about the language and are just here to argue. They use GNU lightning for JIT compiling.


top kek. gnu lightning is not a compiler at all but nothing more than a dynamic assembler. are you really comparing llvm to gnu lightning?



v8 is designed for javascript in mind, luajit is designed for lua, mono is designed for .Net

jit engine's affinity to language is required for performance and something tells me you have never wrote one in your lifetime.

llvm is not jit engine either. you can make jit engine from llvm, but I guarantee you will have miserable time implementing ffi correct with garbage collector.

if you disagree with racket dev's decision you are more than welcome to fork it and do whatever soykaf you want.

it's not like people use racket for performance critical applications anyway.

disclaimer : I don't use racket. I just embed tinyscheme for parsing and that's enough lisp for me.


File: 1478446000823.png (61.63 KB, 200x119, haskal.png)

>llvm is not jit engine either.
maybe it was true 3 years ago till apple started using it with javascript in safari. since then, llvm has been used for jit compilation with great successes.

>jit engine's affinity to language is required for performance and something tells me you have never wrote one in your lifetime.

clojure on java machine
scala on java machine
f# on CLR
dart on v8
kawa on java machine

all those have decent performances despite not using an in-house jit compiler contrary to racket (clojure 6x faster >>19974)

>if you disagree with racket dev's decision you are more than welcome to fork it and do whatever soykaf you want.

>it's not like people use racket for performance critical applications anyway.

My point was that any programming language maintained/implemented by academics are doomed to fail. CPUs with large cores array will be soon the standard but racket is still far behind when it come to parallel computation.

Not that i am talking about Racket, the implementation, not about the Racket programming language.

Now, i am still waiting for a good, satisfying explanation of >>19952


File: 1478449768588.png (64.88 KB, 200x169, nope.jpg)


>local lainon wins another argument with a straw man

So what's the point you want to make by listing all those projects? did i say racket is faster than any of those?

Besides if you want to make fair arguments regarding language affinity of jit engines why don't you compare them based on bytecode they create?

bring results of

1. jvm languages
java, scala, clojure, kawa

2. clr langs
f#, c#

3. v8 langs
dart, javascript

If you want to rant about implementation of lisp compare lisp implementation among lisp implementation. why should anyone give soyfuk about benchmark btw node and racket.

If you are not that guy who whines about mah performance based on random benchmarks at least clearly state what you want to compare based on what criteria.

> good, satisfying explanation

also explain why node is slower in mandelbrot, binary-tree even though it was parallelized.


>const numCPUs = require('os').cpus().length * 2;

> racket the implementation

I'm walking out of this thread as I hate writing about software I did not write|read|use but if you are serious about your questions not to mock academics but to learn the actual inner workings of implementation, why don't you open up new thread regarding status quo of jit engine's performance on SMP environment?

hint : I know you won't


As a rule, anyone who writes "top kek" isn't interested in a serious discussion.


File: 1478450355477.png (19.4 KB, 200x200, diarrhea.jpg)

I gave up /g (and 4ch in general) when they started using kek instead of lulz.

what's wrong with kids these days? I could troll harder without giving the source of benchmark.


oh and I forgot to mention webkit no longer depends on LLVM for low level optimizer.

What a surprise.



Why are let and let* separate constructs?


Sorry if this is a dumb question! It just seems like let and let* do the exact same thing, only let* is more powerful. If that's the case, then why wouldn't they simply alias let to let* and leave everyone with the more powerful version?


If I had to guess the object code produced by let is simpler than let*, or even vice-versa


>also explain why node is slower in mandelbrot, binary-tree even though it was parallelized.

A nodejs sub-process doesn't share its memory with its parent. All the data is send/received through a (local) network socket.

1. The parent process (PP) create an array to hold children buffers
var part_buffer = new Array(numCPUs);
2. Each child process (CP) create a buffer for doing the mandelbrot computation
var buff = new Buffer(d * d / 8 / numCPUs);
3. When the computation is done, CP send the buffer to PP through the shared socket (The data is copied!)


Note that process.send(obj) first converts obj to a json string before sending it (serialization)

4. PP receives the json string which is implicitly deserialized back into an json object.
worker.on('message', function(e) 

5. PP creates a buffer from the json object
part_buffer[this.id - 1] = new Buffer(e.data);

6. When PP has received all the buffers, the data is then write to stdout.
if (alive == 0) {
//var fd = fs.openSync('test3.pbm', 'w');
//fs.writeSync(fd, 'P4\n'+d+' '+d+'\n');
process.stdout.write('P4\n'+d+' '+d+'\n')
for (var i = 0; i < numCPUs; i++) {
//fs.writeSync(fd, part_buffer[i], 0, part_buffer[i].length);

So, this code is very inefficient because each child process buffer is converted to a json object
which is then converted into a string
which is then send to the parent through a socket
the parent then convert the string back into a json object
which is then used to re-create the data buffer.

That a lot of unnecessary data duplication and conversion.


In Racket, let has an additional syntax where you bind the binding lambda as an identifier.
Basically it helps you write recursive routines really easily:
(let my-loop ([n 10] [acc 0])
(if (zero? n) acc (my-loop (- n 1) (+ acc n))))
is the same as
(define (my-loop n acc)
(if (zero? n) acc (my-loop (- n 1) (+ acc n))))
(my-loop 10 0))

You can't do this with let*.



thx for explanation lainon !

I guess it's clear to everybody that just because benchmark website uses it, you cannot assume the program was written to exploit every aspect of language performance wise.



Also, let* will introduce <n> scopes, one per variable (although there are some optimization hacks that can cheapen or eliminate this in some contexts). let will only introduce one:

(let* ((a 10)
(b 12))
(+ a b))

macroexpands (let* is usually implemented as a macro in the schemes, and I think Racket does as well) to

((lambda12 (a)
((lambda18 (b)
(+ a b)) 12)) 10)


(let ((a 10)
(b 12))
(+ a b))

expands to

((lambda8 (a b)
(+ a b)) 10 12)

So let is more efficient than let*, in general.


OOHHHH, that's what that's for. Thanks, anon. What I had been doing all this time for accumulated functions was nesting them via separate defines (e.g., (define (blah x) ... (define (blah/acc x a) ...) (blah/acc x initial-a-value))).

This is very nifty! But I don't know how I feel about breaking consistency with regular define, it makes skimming code much easier.


Its nice for simple recursions, however I find Racket's featureful 'for' synatax(es) to be immensely useful and usually preferrable to recursion (also equivalent).
(let loop ([i 1])
(if (>= i 10)
(cons (* i i)
(loop (+ i 1)))))
(for/list ([i (in-range 1 10)])
(* i i))


Yes, Racket's functional for/ comprehensions are probably one of the most used features for me. For/fold is an incredibly powerful tool. It's a nice extension to standard mapping/folding/etc. procedures.


Does it? I think it makes scoping much clearer (obviously) and lets you define all the variables in one place rather than scattering them all around. I always prefer using lets and named lets over defines inside functions when I'm using a lisp.


I don't know how I feel about it either way, but Racket's style guide says to prefer internal definitions wherever possible. SICP uses internal definitions for functions but lets for variables. Personally I don't think any clarity is gained when using lets over defines. I think if you're using a lot of defines or lets you might want to consider breaking the function up, especially if it's too the point where using one form over the other would result in greater clarity.


Do you think there's a point where inner functions become too big and should be moved out of scope? Or, if I'm never ever going to be referencing the inner logic from other functions, is it good to keep them all inside the bigger function?
Right now I have a function like
(define (apply-route root path)
(define (traverse node path parsed next)
(define (traverse-params params-hash input path-rest parsed next)
(define (traverse-static static-hash input path-rest parsed next)
; actually traverse here
(traverse root path null null))

Each inner function is about 15 LOC, which makes the whole outer function pretty big, but they all perform single tasks, usually accumulating a single list or calling a recursion.


Expert racket programmer. My rules are

1. inner procedure when you need to read parent scope's variables.
2. let over define if you need a default/starting initialization of arguments.

;; note how end is invariant here.
(define (sum-range-loop start end acc)
(if (= start end)
(sum-range (add1 start) end (+ acc start))))

(define (sum-range start end)
(sum-range-loop start end 0))

vs. inner procedure
(define (sum-range start end)
(define (loop s acc) ; loop proc arguments reduced to its variants
(if (= s end) ; invariant referred through parent's scope
(loop (add1 s) (+ acc s))))
(loop start 0))

now, since we need a start initialization ((loop start 0)), it's better to use a let.

(define (sum-range start end)
(let loop ([s start]
[acc 0])
(if (= s end)
(loop (add1 s) (+ acc s)))))

if there no need for a start initialization, i favor define. for example, a function that read 2 numbers, add them then print the result till eof.

(define (loop)
(define a (read))
(define b (read))
(unless (eof-object? a)
(printf "~A " (+ a b))

;; (read) too much redundant here
(let loop ([a (read)]
[b (read)])
(unless (eof-object? a)
(printf "~A " (+ a b))
(loop (read) (read))))


;; (read) too much redundant here
(let loop ([a (read)]
[b (read)])
(unless (eof-object? a)
(printf "~A " (+ a b))
(loop (read) (read))))

is like doing in C

for (inteof a = readnumber(), inteof b = readnumber(); a != EOF; a = readnumber(), b = readnumber())
printf("%d ", a + b);

that's disgusting.


In general you should keep function definitions top-level (i.e., "not internal") unless necessary. Internal functions are necessary for recursion, but majority of those cases are handled by named let (or better yet a function which consumes a list, like map or a fold). I would keep traverse, traverse-params etc. top level even if it means passing some variables around. Have more top level functions means more stuff that can be tested, which means bugs are distributed in a way that lets them be detected easier. When you have internal functions, pinpointing a bug takes longer. You should develop writing one of those internal functions at a time anyway.


Define also allows for default/starting values.
(define (sum-range start end [acc 0])
(if (= start end)
(sum-range (add1 start) end (+ acc start))))
Not much of a difference in a trivial loop example, and I didn't consider using them as accumulators until you posted this, but there it is. When the default argument isn't explicitly initialized (sum-range 0 5 5) vs. (sum-range 0 5) it's called with the default value 0.



How about
(let loop ()
(let ([a (read)])
[b (read)])
(unless (eof-object? a)


why would you use an extra let?


He was working on something called VRScript, which was supposed to be a Scheme-like language.


I don't know if anyone here has heard about this yet but according to Matthew Flatt, Racket's going to be migrating to using the recently open-sourced Chez Scheme language as the base VM for Racket in the next couple of years. It's going to be pretty nifty and bring some nice speed improvements to the language, which is already faster than Python last I checked.


If that happens I would actually start using it


Why don't you use it already?


i would assume it's because the current implementation is the contrary of what you described?

anyway, i like racket, comes with a lot of nifty stuff


File: 1488853183530.png (42.98 KB, 168x200, drunk1.jpg)

Sounds good, but memory usage was the only thing that really bothered me. It wasn't possible to keep multiple services running on a cheapo cloud box. Do you want to post sauce?