What would you use a #[] data literal for?

377 views
Skip to first unread message

vemv

unread,
Dec 28, 2012, 5:15:52 PM12/28/12
to clo...@googlegroups.com
I was just wondering - given that we have the #() and #{} literals, why not a #[] as well? Queues look like a good fit.

Jozef Wagner

unread,
Dec 30, 2012, 6:45:24 AM12/30/12
to clo...@googlegroups.com
I use it in Clojurescript for a custom tuple type. 

For small number of items, deftypes are way faster to create and access than PersistentVectors. I use tuple type e.g. for returning multiple values from a function. Implementing #[] allowed me to have a compact syntax for creating and destructuring such tuples.

(defn foo [a b] 
  #[(+ a b) (- a b) (* a b)])

(defn foo []
  (let [#[plus minus times] (foo 1 2)]
    (str "bla bla" plus "blaah" minus)))

JW

Ambrose Bonnaire-Sergeant

unread,
Dec 30, 2012, 8:38:44 AM12/30/12
to clo...@googlegroups.com
Jozef,

How do you achieve that?

Thanks,
Ambrose

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Jozef Wagner

unread,
Dec 30, 2012, 3:57:00 PM12/30/12
to clo...@googlegroups.com, abonnair...@gmail.com
By patching LispReader in Clojure, http://goo.gl/tWnkq and ClojureScript compiler http://goo.gl/nyKc5 . Used in closed source project, so I can use my own flavor of Clojure there.

JW

Brandon Bloom

unread,
Dec 30, 2012, 7:03:39 PM12/30/12
to clo...@googlegroups.com
Wouldn't it be better to implement this as an automatic optimization, just like PersistentArrayMap vs PersistentHashMap ?

fwiw, I'm cautiously in favor of #[] being used for queues.

dgrnbrg

unread,
Dec 30, 2012, 7:20:11 PM12/30/12
to clo...@googlegroups.com, abonnair...@gmail.com
You can also patch the LispReader in jvm Clojure without dropping to Java. Here's an example of that to add a #b reader literal: https://github.com/dgrnbrg/piplin/blob/master/src/piplin/types/bits.clj#L216

Jozef Wagner

unread,
Dec 31, 2012, 6:48:16 AM12/31/12
to clo...@googlegroups.com, abonnair...@gmail.com
This is great! I will use it for my #[] reader literal. 

Thank you,
JW

Jozef Wagner

unread,
Dec 31, 2012, 7:21:35 AM12/31/12
to clo...@googlegroups.com
Significant performance gain is achieved when destructuring by skipping nth and directly calling type fields instead. Concrete vector implementation is not known when destructuring, so I'm left with a custom reader literal.

I seldom use queues but they seem like a good fit for a #[]

JW

Brandon Bloom

unread,
Dec 31, 2012, 7:40:50 PM12/31/12
to clo...@googlegroups.com
> Significant performance gain is achieved when destructuring by skipping nth and directly calling type fields instead.

Have you also patched the destructuring mechanism?

> Concrete vector implementation is not known when destructuring, so I'm left with a custom reader literal.

How does the reader literal affect the site of destructuring? Are you also using the #[] literal for the destructure target? ie:

(let [#[x y] #[1 2]] ...)

If so, then wouldn't to make more sense to rely on type hints?

(let [[x y] ^Tuple2 (tuple 1 2)] ...)

I guess, potentially, you could rely on the explicit vector type for small literals:

(let [[x y] ^Vec2 [1 2]] ...)

But that seems like a bad idea....

Jozef Wagner

unread,
Jan 1, 2013, 3:01:42 AM1/1/13
to clo...@googlegroups.com
Yes I have patched destructuring, http://goo.gl/Xc23p , and I use #[] for both tuple creation and destructuring, see example in my earlier message.

Type hinting could be a nicer solution, I've never thought of it. Will try.

JW

kovas boguta

unread,
Jan 4, 2013, 8:50:04 AM1/4/13
to clo...@googlegroups.com
One idea is to reserve #[] for a concept that supersedes macros.

For instance, we have yet to apply the concept of protocols to macros.

Another direction is recursive subexpansion, a la mathematica.

If you consider transformations between code and data, there are 4
possibilities:
data->data (this is what a vanilla function does)
code->code (vanilla macros)
code->data (eval in lisp, HoldAll attribute in mathematica)
data->code (compiler)

There is quite a bit of room to play with the interaction and
composition of these operations. Macros are not the end of the road.

Problems that need to be solved include:
- multipass compiler
- feature expressions
- divergence in eval behavior between reader literals like [(+ 1 x)]
and tagged literals like #my/tag (+ 1 x)

On Fri, Dec 28, 2012 at 5:15 PM, vemv <ve...@vemv.net> wrote:
> I was just wondering - given that we have the #() and #{} literals, why not
> a #[] as well? Queues look like a good fit.
>

Jozef Wagner

unread,
Jan 4, 2013, 1:58:35 PM1/4/13
to clo...@googlegroups.com
Hi,

I've reworked my tuple type into an ArrayVector type. Instead of using #[] reader macro, ArrayVector replaces PersistentVector for small vectors and falls back to PersistentVector as it grows. Fast destructuring is achieved with ^ArrayVector hint.

See http://dev.clojure.org/jira/browse/CLJS-453 for patch and more info.

JW

Jim - FooBar();

unread,
Jan 4, 2013, 2:20:45 PM1/4/13
to clo...@googlegroups.com
Greetings and all best wishes for 2013 to everyone!!! :-)

First of all, forgive me for hijacking this thread but I what I started to do originated from this thread and so I feel it is related.

So, for the fun (and the learning) of it, I thought to create a queue literal myself as suggested in this thread. As you might expect I started with function constructor first. That was pretty easy...I settled for something like this:

(defn queue
([] clojure.lang.PersistentQueue/EMPTY)
([& items] (apply conj (queue) items)))

This gives me behaviour like the rest of the ctor fns (vector, list etc etc) so that's good. Now I need a literal the reader can understand so it shows up nicely on the repl. The #[] seems like a reasonable choice for this exercise but from what I understand from reading here ( http://clojure.org/reader#The%20Reader--Tagged%20Literals)   I can't have #[] but rather #foo/[] because r eader tags without namespace qualifiers are reserved for Clojure itself.

So, in the top directory of a dummy project I need a data_readers.clj file with this in: {foo/[]  dummy.foo/queue}.

Can someone please explain how do you then use such literal? Again, from the website I understand that you would use it like this:  #foo/[] [1 2 3 4] while in fact what I'd want is : #foo/[1 2 3 4]. I feel I'm missing something big here... How have other people tried to implement the #[] literal?

thanks a lot in advance!

Jim

Jim - FooBar();

unread,
Jan 4, 2013, 2:39:39 PM1/4/13
to clo...@googlegroups.com
aaaa ok...It turns out I can answer my own question!a blog post by Brian Carper [1] cleared it out for me...I am looking for a custom literal - not a tagged literal and for that one has to patch the reader which I'm sure is not a good idea! anyway it seems I 've misunderstood certain things...back to reading! :-)


[1] http://briancarper.net/blog/449/

Jim
Reply all
Reply to author
Forward
0 new messages