[racket] #lang racket vs. racket/base

191 views
Skip to first unread message

Manfred Lotz

unread,
Feb 12, 2014, 12:02:30 AM2/12/14
to us...@racket-lang.org
I just read Neil van Dyke's statement:

< "#lang racket" is for demos, IMHO; I *always* use "#lang racket/base"
< for any code that's not a demo.

Question: What are the advantages of doing requires explicitly?

In a program of mine I changed #lang racket to #lang racket/base and
added:

(require racket/cmdline)
(require racket/string)
(require racket/format)
(require racket/port)
(require racket/path)
(require racket/list)


The resulting executable (created by raco exe...) had the same size.
Besides of transparency what are the advantages?

--
Manfred


____________________
Racket Users list:
http://lists.racket-lang.org/users

Matthew Flatt

unread,
Feb 12, 2014, 8:07:17 AM2/12/14
to Manfred Lotz, us...@racket-lang.org
At Wed, 12 Feb 2014 06:02:30 +0100, Manfred Lotz wrote:
> I just read Neil van Dyke's statement:
>
> < "#lang racket" is for demos, IMHO; I *always* use "#lang racket/base"
> < for any code that's not a demo.
>
> Question: What are the advantages of doing requires explicitly?
>
> In a program of mine I changed #lang racket to #lang racket/base and
> added:
>
> (require racket/cmdline)
> (require racket/string)
> (require racket/format)
> (require racket/port)
> (require racket/path)
> (require racket/list)
>
>
> The resulting executable (created by raco exe...) had the same size.

I'm surprised that they were the same size, assuming that you didn't
import other libraries that have more dependencies.

With these two files:

r.rkt
-----
#lang racket


b.rkt
-----
#lang racket/base
(require racket/cmdline
racket/string
racket/format
racket/port
racket/path
racket/list)

on my machine, `raco exe b.rkt` produces a 2.4 MB executable, while
`raco exe r.rkt` produces a 5.2MB executable.

There's a similarly significant difference in startup times for me:

laptop% time racket -l racket/base
0.030u 0.013s 0:00.04 100.0% 0+0k 0+0io 0pf+0w
laptop% time racket -l racket/base -l racket/string -l racket/cmdline \
-l racket/format -l racket/port -l racket/path -l racket/list
0.103u 0.029s 0:00.13 92.3% 0+0k 0+0io 0pf+0w
laptop% time racket -l racket
0.155u 0.041s 0:00.19 100.0% 0+0k 0+0io 0pf+0w

Footprint and startup time are the main reasons to use `racket/base`
plus explicit imports instead of `racket`.

Greg Hendershott

unread,
Feb 12, 2014, 8:26:07 AM2/12/14
to Manfred Lotz, us...@racket-lang.org
Although I could be mistaken about any/all of the following, I'll go
out on a limb -- and once there, jump up and down.

> < "#lang racket" is for demos, IMHO; I *always* use "#lang racket/base"
> < for any code that's not a demo.
>
> Question: What are the advantages of doing requires explicitly?

I'm under the impression that the advantages are (a) faster load time
and (b) smaller memory footprint.

> The resulting executable (created by raco exe...) had the same size.

It should have a smaller size.

But also:

My impression is that `raco exe` predates the rise of "scripting
languages" like Python and Ruby, in which it's common to tell users,
"Make sure you have version X of Python or Ruby, then install my app".

To be clear, I'm not saying Racket is "just a scripting language". And
I'm not saying that it's wrong for someone to want "an executable" if
they need that for a certain situation. But I am speculating that
fewer users will expect it (for some definition of "users") these
days.

Finally, a lot of work over the past year+ went into a new package
system for Racket. Not only is this for third party libraries, it's
for huge swaths of Racket itself. (IOW almost no distinction between
"third party" and "Racket lib".)

Given that, you could have people install a very minimal Racket core,
and then install your package -- during which the package manager will
download/install only what else is needed by your package.

---

Just as I was about to hit send, Matthew's post arrived. I'll post mine anyway.

Manfred Lotz

unread,
Feb 12, 2014, 8:59:01 AM2/12/14
to us...@racket-lang.org
On Wed, 12 Feb 2014 06:07:17 -0700
Matthew Flatt <mfl...@cs.utah.edu> wrote:

> At Wed, 12 Feb 2014 06:02:30 +0100, Manfred Lotz wrote:
> > I just read Neil van Dyke's statement:
> >
> > < "#lang racket" is for demos, IMHO; I *always* use "#lang
> > racket/base" < for any code that's not a demo.
> >
> > Question: What are the advantages of doing requires explicitly?
> >
> > In a program of mine I changed #lang racket to #lang racket/base and
> > added:
> >
> > (require racket/cmdline)
> > (require racket/string)
> > (require racket/format)
> > (require racket/port)
> > (require racket/path)
> > (require racket/list)
> >
> >
> > The resulting executable (created by raco exe...) had the same size.
>
> I'm surprised that they were the same size, assuming that you didn't
> import other libraries that have more dependencies.
>
> With these two files:
>
> r.rkt
> -----
> #lang racket
>
>

My system is a 64 bit Fedora 20.

Size here is: 5045135

> b.rkt
> -----
> #lang racket/base
> (require racket/cmdline
> racket/string
> racket/format
> racket/port
> racket/path
> racket/list)
>
> on my machine, `raco exe b.rkt` produces a 2.4 MB executable, while
> `raco exe r.rkt` produces a 5.2MB executable.
>

Hm, ok you are right. This one has size: 2123527

I had to add more stuff:

racket/date which makes it much larger: 4029753


(require openssl)
(require openssl/sha1)

which makes a size of: 4511202


In my source I found a mistake. I had a require for a file.rkt
which still had racket instead of racket/base. Changing this saved me 1
MB compared to the initial 5602007 bytes size.


> There's a similarly significant difference in startup times for me:
>
> laptop% time racket -l racket/base
> 0.030u 0.013s 0:00.04 100.0% 0+0k 0+0io 0pf+0w
> laptop% time racket -l racket/base -l racket/string -l
> racket/cmdline \ -l racket/format -l racket/port -l racket/path -l
> racket/list 0.103u 0.029s 0:00.13 92.3% 0+0k 0+0io 0pf+0w
> laptop% time racket -l racket
> 0.155u 0.041s 0:00.19 100.0% 0+0k 0+0io 0pf+0w
>

These times are similar on my system.



--
Manfred

Robby Findler

unread,
Feb 12, 2014, 10:55:16 AM2/12/14
to Manfred Lotz, Racket Users
Looks like most of the size increase from racket/date is that you're pulling in the contract system. Still, there was some dead code in that file whose removal let me remove a few requires from it (eliminating a dependency on racket/match, since none of the things racket/date requires require it). I'll push those changes later on today.

Robby

Manfred Lotz

unread,
Feb 13, 2014, 4:36:27 PM2/13/14
to us...@racket-lang.org
On Wed, 12 Feb 2014 09:55:16 -0600
Robby Findler <ro...@eecs.northwestern.edu>
wrote:

> Looks like most of the size increase from racket/date is that you're
> pulling in the contract system.

No quite sure about this.

I have

#lang racket/base

(require racket/cmdline
racket/string
racket/format
racket/port
racket/path
racket/list)

which gives a size of 2123435 for the executable.

I add one line
(require racket/date)
and the executable has size 4029647

Is there something implicit happening with the contract system?

Robby Findler

unread,
Feb 13, 2014, 5:12:44 PM2/13/14
to Manfred Lotz, Racket Users
Oh, apparently the difference you're seeing is indeed racket/match. I see that the contract system is already pulled in with those requires -- it is bigger than racket/match. (You can see what libraries are indirectly loaded by using DrRacket's View|Show Module Browser.)

Anyway, in the current git version (with the change to racket/date I mentioned yesterday), I get 2.2M for the version without racket/date and 2.3 for the version with. But in 5.94, I see 3.9M for the version with racket/date.

Robby

Manfred Lotz

unread,
Feb 14, 2014, 3:24:27 PM2/14/14
to us...@racket-lang.org
On Thu, 13 Feb 2014 16:12:44 -0600
Robby Findler <ro...@eecs.northwestern.edu>
wrote:

> Oh, apparently the difference you're seeing is indeed racket/match. I
> see that the contract system is already pulled in with those requires
> -- it is bigger than racket/match. (You can see what libraries are
> indirectly loaded by using DrRacket's View|Show Module Browser.)
>
> Anyway, in the current git version (with the change to racket/date I
> mentioned yesterday), I get 2.2M for the version without racket/date
> and 2.3 for the version with. But in 5.94, I see 3.9M for the version
> with racket/date.
>
> Robby
>
>

Thanks for explaining and optimizing. The new space utilization in
current sounds really great.

--
Manfred

Yuhao Dong

unread,
Feb 12, 2014, 10:39:44 AM2/12/14
to us...@racket-lang.org

> My impression is that `raco exe` predates the rise of "scripting
> languages" like Python and Ruby, in which it's common to tell users,
> "Make sure you have version X of Python or Ruby, then install my app".

I would say that "raco exe" is rather useless, and I don't see the point
really. It still creates a dependency on Racket to run (you need raco
distribute for redistributable packages) but somehow produces something
giant.

Can somebody please teach me what the real use of "raco exe" is?
signature.asc
Reply all
Reply to author
Forward
0 new messages