From: Leslie P. Polzer
Subject: Clojure hash table accessors in CL
Date: 
Message-ID: <47f1f8ae-bf53-4224-9564-28496de98c3a@r37g2000prr.googlegroups.com>
Clojure, from what I've gathered, lets one access hash tables just by
referring to them in the CAR of an evaluated form:

(defparameter ht (make-hash-table))

(ht 'foo) == (gethash 'foo ht)
(setf (ht 'foo) t) == (setf (gethash 'foo ht) t)

It should be easy to emulate the hash table reader at least in
function context, by defining a custom DEFUN-wrapping macro that
dispatches either to FUNCALL or to GETHASH depending on the data type.

Is this also possible for the SETF expansion? I think it should be,
but I hardly ever use the DEFSETF facilities so I'm not sure how.

  Leslie

From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <6b78dad9-c9ad-4e01-8190-61e4057111c8@k1g2000prb.googlegroups.com>
On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
> Clojure, from what I've gathered, lets one access hash tables just by
> referring to them in the CAR of an evaluated form:
>
> (defparameter ht (make-hash-table))
>
> (ht 'foo) == (gethash 'foo ht)
Actually I feel that as too verbose:
(ht 'foo)
->foo-val
would be even better.
also I want below too for multiple keys selection:
(ht '(foo bar baz))
-> (foo-val bar-val baz-val)
and possibly even this:
(ht (lambda (key) (like (princ-to-string key) "*-bar"))))

bobi

> (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> It should be easy to emulate the hash table reader at least in
> function context, by defining a custom DEFUN-wrapping macro that
> dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> Is this also possible for the SETF expansion? I think it should be,
> but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
>   Leslie
From: ······@corporate-world.lisp.de
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <d30f2468-6ef6-4f0d-bc17-22c7e5eee599@b41g2000pra.googlegroups.com>
On Dec 14, 1:37 pm, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:> Clojure, from what I've gathered, lets one access hash tables just by
> > referring to them in the CAR of an evaluated form:
>
> > (defparameter ht (make-hash-table))
>
> > (ht 'foo) == (gethash 'foo ht)
>
> Actually I feel that as too verbose:
> (ht 'foo)
> ->foo-val
> would be even better.
> also I want below too for multiple keys selection:
> (ht '(foo bar baz))
> -> (foo-val bar-val baz-val)
> and possibly even this:
> (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
>
> bobi
>
> > (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> > It should be easy to emulate the hash table reader at least in
> > function context, by defining a custom DEFUN-wrapping macro that
> > dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> > Is this also possible for the SETF expansion? I think it should be,
> > but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
> >   Leslie

If you want to go that route, why not make $ a default hash-table
variable and $foo accesses it.
Also write $ht.foo to access hash table ht. Then make $h.f!3 set the
hash table h, key f to 3.
Not that it would look like Lisp, but it sure saves keystrokes.
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <42388370-ac11-4851-b3ec-aa43c3a21585@k1g2000prb.googlegroups.com>
On Dec 14, 2:01 pm, ·······@corporate-world.lisp.de" <······@corporate-
world.lisp.de> wrote:
> On Dec 14, 1:37 pm, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
>
>
> > On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:> Clojure, from what I've gathered, lets one access hash tables just by
> > > referring to them in the CAR of an evaluated form:
>
> > > (defparameter ht (make-hash-table))
>
> > > (ht 'foo) == (gethash 'foo ht)
>
> > Actually I feel that as too verbose:
> > (ht 'foo)
> > ->foo-val
> > would be even better.
> > also I want below too for multiple keys selection:
> > (ht '(foo bar baz))
> > -> (foo-val bar-val baz-val)
> > and possibly even this:
> > (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
>
> > bobi
>
> > > (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> > > It should be easy to emulate the hash table reader at least in
> > > function context, by defining a custom DEFUN-wrapping macro that
> > > dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> > > Is this also possible for the SETF expansion? I think it should be,
> > > but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
> > >   Leslie
>
> If you want to go that route, why not make $ a default hash-table
> variable and $foo accesses it.
> Also write $ht.foo to access hash table ht. Then make $h.f!3 set the
> hash table h, key f to 3.
> Not that it would look like Lisp, but it sure saves keystrokes.

Because I need a general solution. Every instance container is in the
same time a function that takes a key, suit of keys or a predicate.
(setq lst (list 1 2 3))
(setq arr (array 1 2 3))

(lst 1)
2
(arr 1)
2
(lst 0 2)
(1 3)
(arr 0 2)
(1 3)

bobi
From: Pascal J. Bourguignon
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <7ciqpld1gq.fsf@pbourguignon.anevia.com>
Slobodan Blazeski <·················@gmail.com> writes:

> On Dec 14, 2:01�pm, ·······@corporate-world.lisp.de" <······@corporate-
> world.lisp.de> wrote:
>> On Dec 14, 1:37 pm, Slobodan Blazeski <·················@gmail.com>
>> wrote:
>>
>>
>>
>> > On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:> Clojure, from what I've gathered, lets one access hash tables just by
>> > > referring to them in the CAR of an evaluated form:
>>
>> > > (defparameter ht (make-hash-table))
>>
>> > > (ht 'foo) == (gethash 'foo ht)
>>
>> > Actually I feel that as too verbose:
>> > (ht 'foo)
>> > ->foo-val
>> > would be even better.
>> > also I want below too for multiple keys selection:
>> > (ht '(foo bar baz))
>> > -> (foo-val bar-val baz-val)
>> > and possibly even this:
>> > (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
>>
>> > bobi
>>
>> > > (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>>
>> > > It should be easy to emulate the hash table reader at least in
>> > > function context, by defining a custom DEFUN-wrapping macro that
>> > > dispatches either to FUNCALL or to GETHASH depending on the data type.
>>
>> > > Is this also possible for the SETF expansion? I think it should be,
>> > > but I hardly ever use the DEFSETF facilities so I'm not sure how.
>>
>> > > � Leslie
>>
>> If you want to go that route, why not make $ a default hash-table
>> variable and $foo accesses it.
>> Also write $ht.foo to access hash table ht. Then make $h.f!3 set the
>> hash table h, key f to 3.
>> Not that it would look like Lisp, but it sure saves keystrokes.
>
> Because I need a general solution. Every instance container is in the
> same time a function that takes a key, suit of keys or a predicate.
> (setq lst (list 1 2 3))
> (setq arr (array 1 2 3))

(defun list (&rest elements)
  (lambda (start &optional end)
    (if end (subseq elements start end) (elt element start))))
(defun vector (&rest elements)
  (lambda (start &optional end)
    (if end (subseq elements start end) (elt element start))))

;; and for backward compatibility:

(defun svref (vector index)
  (funcall vector index))


> (lst 1)

(funcall lst 1)

> 2
> (arr 1)

(funcall arr 1)

> 2
> (lst 0 2)
> (1 3)
> (arr 0 2)
> (1 3)

etc.  We bump once again against the lisp-2 fundamental philosophical choice.

-- 
__Pascal Bourguignon__
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <1b5c1b5f-1598-4ad2-bec9-8377ece35885@u18g2000pro.googlegroups.com>
On Dec 15, 2:15 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Slobodan Blazeski <·················@gmail.com> writes:
> > On Dec 14, 2:01 pm, ·······@corporate-world.lisp.de" <······@corporate-
> > world.lisp.de> wrote:
> >> On Dec 14, 1:37 pm, Slobodan Blazeski <·················@gmail.com>
> >> wrote:
>
> >> > On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:> Clojure, from what I've gathered, lets one access hash tables just by
> >> > > referring to them in the CAR of an evaluated form:
>
> >> > > (defparameter ht (make-hash-table))
>
> >> > > (ht 'foo) == (gethash 'foo ht)
>
> >> > Actually I feel that as too verbose:
> >> > (ht 'foo)
> >> > ->foo-val
> >> > would be even better.
> >> > also I want below too for multiple keys selection:
> >> > (ht '(foo bar baz))
> >> > -> (foo-val bar-val baz-val)
> >> > and possibly even this:
> >> > (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
>
> >> > bobi
>
> >> > > (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> >> > > It should be easy to emulate the hash table reader at least in
> >> > > function context, by defining a custom DEFUN-wrapping macro that
> >> > > dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> >> > > Is this also possible for the SETF expansion? I think it should be,
> >> > > but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
> >> > >   Leslie
>
> >> If you want to go that route, why not make $ a default hash-table
> >> variable and $foo accesses it.
> >> Also write $ht.foo to access hash table ht. Then make $h.f!3 set the
> >> hash table h, key f to 3.
> >> Not that it would look like Lisp, but it sure saves keystrokes.
>
> > Because I need a general solution. Every instance container is in the
> > same time a function that takes a key, suit of keys or a predicate.
> > (setq lst (list 1 2 3))
> > (setq arr (array 1 2 3))
>
> (defun list (&rest elements)
>   (lambda (start &optional end)
>     (if end (subseq elements start end) (elt element start))))
No what I want is below
(defun list1 (&rest elements)
  (lambda (&rest indices)
    (mapcar  (lambda (i)
                (if (integerp i)
                   (nth i elements)
                   (remove-if-not i elements)))
       indices)))
(setq foo (list1 1 2 3 4))
#<anonymous interpreted function 2175412A>

CL-USER 14 : 3 > (funcall foo 0 1 2 #'oddp)
(1 2 3 (1 3))

> (defun vector (&rest elements)
>   (lambda (start &optional end)
>     (if end (subseq elements start end) (elt element start))))
>
> ;; and for backward compatibility:
>
> (defun svref (vector index)
>   (funcall vector index))
>
> > (lst 1)
>
> (funcall lst 1)
>
> > 2
> > (arr 1)
>
> (funcall arr 1)
>
> > 2
> > (lst 0 2)
> > (1 3)
> > (arr 0 2)
> > (1 3)
>
> etc.  We bump once again against the lisp-2 fundamental philosophical choice.
>
> --
> __Pascal Bourguignon__
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4945118e$0$90274$14726298@news.sunsite.dk>
 SB> also I want below too for multiple keys selection:
 SB> (ht '(foo bar baz))
 SB> -> (foo-val bar-val baz-val)

this is a delirium. what if you actually want to lookup key '(foo bar baz)?
i have keys that are lists all the time 
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <ea808a2f-a941-4d69-b520-938f77d9ee34@s1g2000prg.googlegroups.com>
On Dec 14, 3:00 pm, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  SB> also I want below too for multiple keys selection:
>  SB> (ht '(foo bar baz))
>  SB> -> (foo-val bar-val baz-val)
>
> this is a delirium. what if you actually want to lookup key '(foo bar baz)?
> i have keys that are lists all the time

Excellent question Alex. It could be easily solved with adding more
syntax or no agregate keys. I will have to think about it.

bobi
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <98fbc3fb-8b54-46f7-87f6-a715978c85b1@s37g2000vbp.googlegroups.com>
On Dec 15, 9:13 am, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Dec 14, 3:00 pm, "Alex Mizrahi" <········@users.sourceforge.net>
> wrote:
>
> >  SB> also I want below too for multiple keys selection:
> >  SB> (ht '(foo bar baz))
> >  SB> -> (foo-val bar-val baz-val)
>
> > this is a delirium. what if you actually want to lookup key '(foo bar baz)?
> > i have keys that are lists all the time
>
> Excellent question Alex. It could be easily solved with adding more
> syntax or no agregate keys. I will have to think about it.
>
> bobi

Solved  it, &rest is my friend :)
(ht  '(foo bar baz)  1 'foo)
->(foo-bar-baz-value 1-value foo-value)

I love design by newsgroup.

bobi
P.S.
This is all for my language, edi. I don't  want this added to common
lisp.
From: André Thieme
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <gi3c2f$ma7$1@news.motzarella.org>
Slobodan Blazeski schrieb:
> On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
>> Clojure, from what I've gathered, lets one access hash tables just by
>> referring to them in the CAR of an evaluated form:
>>
>> (defparameter ht (make-hash-table))
>>
>> (ht 'foo) == (gethash 'foo ht)
> Actually I feel that as too verbose:
> (ht 'foo)
> ->foo-val
> would be even better.

Let�s say we have two hashmaps:
(def h1 {:name "Slobodan" :foo 100 :language "Lisp"})
(def h2 {:name "Slodoban" :foo 200 :language "Perl"})

(print :foo-val)  ==> will it print 100 or 200?
(print (:foo h1)) ==> prints 100 and is not dramatically much verbose.


> also I want below too for multiple keys selection:
> (ht '(foo bar baz))
> -> (foo-val bar-val baz-val)

Something similar is available in Clojure:
user> (let [{:keys [foo name]} h2]
         [(inc foo) name])
==>
[201 "Slodoban"]

or
user> [(:foo h2) (h2 :name)]
[200 "Slodoban"]

When keywords (symbols with a : in the front) were used then these
keywords act as getter function. But one can in general also have the
collection object first and then the key:
([10 20 30] 1) ==> 20

But your suggestion of (ht '(foo bar baz)) is really not good, as Alex
already mentioned. People want to have the list (foo bar baz) as the key
for their hash map.



> and possibly even this:
> (ht (lambda (key) (like (princ-to-string key) "*-bar"))))

This would not be very orthogonal to what is already available and thus
is not a good idea.
And how could we decide if it will map over the keys or the values or
the key/value pairs?

Why not just (map #(like (str %) "*-bar") (keys ht)) to get all keys
that end with "-bar"?
Or instead of map you could
(first (filter #(like (str %) "*-bar") (keys ht)))


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <6b7683fa-f66f-49c3-8d2a-c9a45561a3af@a26g2000prf.googlegroups.com>
On Dec 14, 5:25 pm, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Slobodan Blazeski schrieb:
>
> > On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
> >> Clojure, from what I've gathered, lets one access hash tables just by
> >> referring to them in the CAR of an evaluated form:
>
> >> (defparameter ht (make-hash-table))
>
> >> (ht 'foo) == (gethash 'foo ht)
> > Actually I feel that as too verbose:
> > (ht 'foo)
> > ->foo-val
> > would be even better.
>
> Let’s say we have two hashmaps:
> (def h1 {:name "Slobodan" :foo 100 :language "Lisp"})
> (def h2 {:name "Slodoban" :foo 200 :language "Perl"})
Braces, no way. That's too much syntax already I'm thinking of using
() for point-free definitions but that already looks ugly.
>
> (print :foo-val)  ==> will it print 100 or 200?
> (print (:foo h1)) ==> prints 100 and is not dramatically much verbose.
>
> > also I want below too for multiple keys selection:
> > (ht '(foo bar baz))
> > -> (foo-val bar-val baz-val)
>
> Something similar is available in Clojure:
> user> (let [{:keys [foo name]} h2]
>          [(inc foo) name])
> ==>
> [201 "Slodoban"]
>
> or
> user> [(:foo h2) (h2 :name)]
> [200 "Slodoban"]
>
> When keywords (symbols with a : in the front) were used then these
> keywords act as getter function. But one can in general also have the
> collection object first and then the key:
> ([10 20 30] 1) ==> 20
>
> But your suggestion of (ht '(foo bar baz)) is really not good, as Alex
> already mentioned. People want to have the list (foo bar baz) as the key
> for their hash map.
>
> > and possibly even this:
> > (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
>
> This would not be very orthogonal to what is already available and thus
> is not a good idea.
> And how could we decide if it will map over the keys or the values or
> the key/value pairs?
Good question. If I have a list :
(setq lst (list 1 2 3 4 5))
and I do:
(lst #'oddp)
what should the result be?
(1 3 5)
So the predicate loops over container values. For looping over keys
there should be something else.
>
> Why not just (map #(like (str %) "*-bar") (keys ht)) to get all keys
> that end with "-bar"?
> Or instead of map you could
 I don't understand below example
> (first (filter #(like (str %) "*-bar") (keys ht)))
1st we agreed it's over values.   But let's *PRETEND* it's over keys
Whats' more understandable:
(map #'predicate (keys ht)) or
(ht #'predicate)

2nd map is generalized operator it could operate over multiple
containers:
(map #'> '(1 2 3) '(2 3 4))
while  (container key(s)) or (container predicate) is a current
container accessor.

bobi
>
> André
> --
> Lisp is not dead. It’s just the URL that has changed:http://clojure.org/
From: André Thieme
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <gi6r8c$6v2$1@news.motzarella.org>
Slobodan Blazeski schrieb:
> On Dec 14, 5:25 pm, Andr� Thieme <address.good.until.
> ···········@justmail.de> wrote:
>> Slobodan Blazeski schrieb:
>>
>>> On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
>>>> Clojure, from what I've gathered, lets one access hash tables just by
>>>> referring to them in the CAR of an evaluated form:
>>>> (defparameter ht (make-hash-table))
>>>> (ht 'foo) == (gethash 'foo ht)
>>> Actually I feel that as too verbose:
>>> (ht 'foo)
>>> ->foo-val
>>> would be even better.
>> Let�s say we have two hashmaps:
>> (def h1 {:name "Slobodan" :foo 100 :language "Lisp"})
>> (def h2 {:name "Slodoban" :foo 200 :language "Perl"})
> Braces, no way. That's too much syntax already I'm thinking of using
> () for point-free definitions but that already looks ugly.

Well, if you don�t like the extra syntax then you will have to
stay with typing and reading more:
(get ht key)

In my opinion it makes sense to allow easy access to very common
operations.
The {} and [] give your eyes something to stick to.
Lists store mostly programs in Clojure, while for many things one
will use vectors instead.
But sure, if you dislike to see symbols like these in your code then
it�s probably not really interesting to you.


>>> and possibly even this:
>>> (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
>> This would not be very orthogonal to what is already available and thus
>> is not a good idea.
>> And how could we decide if it will map over the keys or the values or
>> the key/value pairs?
> Good question. If I have a list :
> (setq lst (list 1 2 3 4 5))
> and I do:
> (lst #'oddp)
> what should the result be?
> (1 3 5)

I think the result should be an error.
I see no reason why stuff like that should evaluate.
And even if you want to do it, why give the preference to filter?
Why shouldn�t (lst +) be the same as (reduce + lst)?
Or why not mapping?
There are tons of functions that operate on collections.
Picking one of them seems to be too arbitrary.


>> Why not just (map #(like (str %) "*-bar") (keys ht)) to get all keys
>> that end with "-bar"?
>> Or instead of map you could
>  I don't understand below example
>> (first (filter #(like (str %) "*-bar") (keys ht)))

#(like (str %) "*-bar") ===
(fn [x]
   (like (str x) "*-bar"))  where fn is lambda in CL.
(first (filter ...)) is like CLs find.


> 1st we agreed it's over values.   But let's *PRETEND* it's over keys
> Whats' more understandable:
> (map #'predicate (keys ht)) or
> (ht #'predicate)

The first version is more understandable. It tells me what you want to
do. But the second could mean tons of stuff. Which of the 900 functions
that work on collections would we like to call?
Or is it just a hashmap lookup, where you want to get the value which
has the function "predicate" as its key?


Andr�
-- 
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <8be68d6b-baa2-4701-a4df-c3746ac62f4c@i18g2000prf.googlegroups.com>
On Dec 16, 1:03 am, André Thieme <address.good.until.
···········@justmail.de> wrote:
> Slobodan Blazeski schrieb:
>
>
>
> > On Dec 14, 5:25 pm, André Thieme <address.good.until.
> > ···········@justmail.de> wrote:
> >> Slobodan Blazeski schrieb:
>
> >>> On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
> >>>> Clojure, from what I've gathered, lets one access hash tables just by
> >>>> referring to them in the CAR of an evaluated form:
> >>>> (defparameter ht (make-hash-table))
> >>>> (ht 'foo) == (gethash 'foo ht)
> >>> Actually I feel that as too verbose:
> >>> (ht 'foo)
> >>> ->foo-val
> >>> would be even better.
> >> Let’s say we have two hashmaps:
> >> (def h1 {:name "Slobodan" :foo 100 :language "Lisp"})
> >> (def h2 {:name "Slodoban" :foo 200 :language "Perl"})
> > Braces, no way. That's too much syntax already I'm thinking of using
> > () for point-free definitions but that already looks ugly.
>
> Well, if you don’t like the extra syntax then you will have to
> stay with typing and reading more:
> (get ht key)
>
> In my opinion it makes sense to allow easy access to very common
> operations.
> The {} and [] give your eyes something to stick to.
> Lists store mostly programs in Clojure, while for many things one
> will use vectors instead.
> But sure, if you dislike to see symbols like these in your code then
> it’s probably not really interesting to you.
In edi I'm using  brackets instead of parens, and I got parens planned
for tacit(pointfree) definitions and already looks little ugly.  So I
want to keep curly braces {} for the type system if I decide to add
it. So there is no way spending curlies on something else.
>
> >>> and possibly even this:
> >>> (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
> >> This would not be very orthogonal to what is already available and thus
> >> is not a good idea.
> >> And how could we decide if it will map over the keys or the values or
> >> the key/value pairs?
> > Good question. If I have a list :
> > (setq lst (list 1 2 3 4 5))
> > and I do:
> > (lst #'oddp)
> > what should the result be?
> > (1 3 5)
>
> I think the result should be an error.
> I see no reason why stuff like that should evaluate.
> And even if you want to do it, why give the preference to filter?
> Why shouldn’t (lst +) be the same as (reduce + lst)?
> Or why not mapping?
> There are tons of functions that operate on collections.
> Picking one of them seems to be too arbitrary.
Every language designer must make a choices. For me I see (container
&rest predicates) as a natural thing. Predicates might being array
index, list nth element, hash key because they could be inferred from
the element type. So (lst 4) is just a  shortcut for (lst (lambda (x)
(nth 4 lst)) because every container has it's default accessor.
Of course what's natural for me might be silly to you. The beauty is
in the eye of the beholder.
>
> >> Why not just (map #(like (str %) "*-bar") (keys ht)) to get all keys
> >> that end with "-bar"?
> >> Or instead of map you could
> >  I don't understand below example
> >> (first (filter #(like (str %) "*-bar") (keys ht)))
>
> #(like (str %) "*-bar") ===
> (fn [x]
>    (like (str x) "*-bar"))  where fn is lambda in CL.
> (first (filter ...)) is like CLs find.
>
> > 1st we agreed it's over values.   But let's *PRETEND* it's over keys
> > Whats' more understandable:
> > (map #'predicate (keys ht)) or
> > (ht #'predicate)
>
> The first version is more understandable. It tells me what you want to
> do. But the second could mean tons of stuff. Which of the 900 functions
> that work on collections would we like to call?
It depends on the type of the predicate and type of collection.If you
use non function predicate than (ht 4) goes to gethash with key 4, if
it's array aref with index 4, if it's a list nth 4 .. On the other
side if you provide a function as predicate you'll be filtering over
values.

> Or is it just a hashmap lookup, where you want to get the value which
> has the function "predicate" as its key?
Very good question.  Answer: You can't use functions as keys. Another
real world issue squashed.

cheers
bobi
>
> André
> --
From: Pascal J. Bourguignon
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <87bpve4674.fsf@informatimago.com>
André Thieme <······························@justmail.de> writes:

> Slobodan Blazeski schrieb:
>> On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
>>> Clojure, from what I've gathered, lets one access hash tables just by
>>> referring to them in the CAR of an evaluated form:
>>>
>>> (defparameter ht (make-hash-table))
>>>
>>> (ht 'foo) == (gethash 'foo ht)
>> Actually I feel that as too verbose:
>> (ht 'foo)
>> ->foo-val
>> would be even better.
>
> Let’s say we have two hashmaps:

It's quite incredible.  Why people aren't trying to add syntaxes to
languages such as pascal or C++ to be able to access maps or vectors
as if was a function call,  but periodically we get asked this kind of 
crapiness here?

Please, just ignore these questions, until we see them asked in clc++ or
similarly in other cl* groups:

    What can be done to be able to write:

        int f(){
           std::map<std::string,int> m;
           m("toto")=42;
           return m("toto");
        }

    in C++?

-- 
__Pascal Bourguignon__
From: D Herring
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4945c9a3$0$17067$6e1ede2f@read.cnntp.org>
Pascal J. Bourguignon wrote:
>     What can be done to be able to write:
> 
>         int f(){
>            std::map<std::string,int> m;
>            m("toto")=42;
>            return m("toto");
>         }

This is generally written as

int f(){
    std::map<std::string,int> m;
    m["toto"]=42;
    return m["toto"];
}

This works because of the following prototype:
mapped_type & operator[](const key_type &);

Although they could have chosen to define it as
mapped_type & operator()(const key_type &);


- Daniel
From: Vsevolod
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <ae62b10d-8622-4c7a-8bd9-0db9c404d65e@o40g2000prn.googlegroups.com>
On Dec 15, 5:06 am, D Herring <········@at.tentpost.dot.com> wrote:
> Pascal J. Bourguignon wrote:
> >     What can be done to be able to write:
>
> >         int f(){
> >            std::map<std::string,int> m;
> >            m("toto")=42;
> >            return m("toto");
> >         }
>
> This is generally written as
>
> int f(){
>     std::map<std::string,int> m;
>     m["toto"]=42;
>     return m["toto"];
>
> }
>
> This works because of the following prototype:
> mapped_type & operator[](const key_type &);
>
> Although they could have chosen to define it as
> mapped_type & operator()(const key_type &);

Well, is it possible to extend such syntax -- [] -- to handle, for
example, multiple keys access at once (as mentioned above in the
thread) or default value? AFAIK with [] -- not, because it's hardwired
to take only 1 argument. Although, you can do it with (). But once
again, can this accessor be extended to handle variable number of
keys?..
From: Kaz Kylheku
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <20090101011731.31@gmail.com>
On 2008-12-15, Pascal J. Bourguignon <···@informatimago.com> wrote:
> André Thieme <······························@justmail.de> writes:
>
>> Slobodan Blazeski schrieb:
>>> On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
>>>> Clojure, from what I've gathered, lets one access hash tables just by
>>>> referring to them in the CAR of an evaluated form:
>>>>
>>>> (defparameter ht (make-hash-table))
>>>>
>>>> (ht 'foo) == (gethash 'foo ht)
>>> Actually I feel that as too verbose:
>>> (ht 'foo)
>>> ->foo-val
>>> would be even better.
>>
>> Let’s say we have two hashmaps:
>
> It's quite incredible.  Why people aren't trying to add syntaxes to
> languages such as pascal or C++ to be able to access maps or vectors
> as if was a function call,  but periodically we get asked this kind of 
> crapiness here?

Objects can be accessed as function calls in C++.

>
> Please, just ignore these questions, until we see them asked in clc++ or
> similarly in other cl* groups:
>
>     What can be done to be able to write:
>
>         int f(){
>            std::map<std::string,int> m;
>            m("toto")=42;
>            return m("toto");
>         }

You can't, because the operator () must be a nonstatic member
function. You can't add anything to the standard class, so that's that.

Using inheritance, we can derive a map which has a () operator:

#include <map>
#include <string>
#include <cstdio>

template <class KEY, class VALUE, class COMPARATOR = std::less<KEY> >
class fmap : public std::map<KEY, VALUE, COMPARATOR>
{
public:
  // [ ... repeat every goddamn constructor like a monkey, etc. ]

  VALUE &operator ()(const KEY &key)
  {
    return operator[](key);
  }
};

int main()
{
  fmap<std::string, int> fm;
  fm("abcd") = 3;
  printf("fm(\"%s\") == %d\n", "abcd", fm("abcd"));
  return 0;
}

This is really stupid because the map actually gives you a reference (pointer
in sheep's clothing) to a storage location where you store the value.

This whole idiotic business of returning the reference to the value out of the
[] operator comes from not having the equivalent of DEFINE-SETF-EXPANDER.

You should be able to write a different method for [] when it is the target of
an assignment.  Moreover, there should be a way to do an efficient operations
that combine a read with update, like what we have with SETF.

Say, what would happen if you were to capture that storage location, manipulate
the map, and then store something using the original location?

Let's change the program a little bit:

int main()
{
  fmap<std::string, int> fm;
  int &captured_ref = fm("abcd");
  fm("abcd") = 3;
  fm.erase("abcd");
  captured_ref = 42;
  printf("fm(\"%s\") == %d\n", "abcd", fm("abcd"));
  captured_ref = 42;
  printf("fm(\"%s\") == %d\n", "abcd", fm("abcd"));
  return 0;
}

An old version of g++ I have lying around (3.4.3) compiles this with no
diagnostics (-Wall -ansi -pedantic).

The output?

$ ./a.out
fm("abcd") == 0
fm("abcd") == 42

What????  The fm.erase operation would have blown off the red-black tree node,
leaving captured_ref dangling. The assignment is stomping on heap
memory that no longer belongs to the reference.

C++ references are not safe pointers. It's trivial to create invalid
references in programs that compile without a peep.

What does Valgrind say when we run this program? We get better output
if we recompile for debugging with g++ -g first:


$ g++ -Wall -ansi -pedantic -g map.cc
$ valgrind --tool=memcheck ./a.out
==25907== Memcheck, a memory error detector for x86-linux.
==25907== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==25907== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==25907== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==25907== For more details, rerun with: -v
==25907==
==25907== Invalid write of size 4
==25907==    at 0x8048AED: main (map.cc:23)

This is the first assignment through captured_ref.  Line 23 of main.

==25907==  Address 0x1B925084 is 20 bytes inside a block of size 24 free'd
==25907==    at 0x1B905043: operator delete(void*) (vg_replace_malloc.c:156)

And this is the call stack of the activation chain that deleted
the object which was being wrongly written:

==25907==    by 0x80498FE: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, int> > >::deallocate(std::_Rb_tree_node<std::pair<std::string const, int> >*, unsigned) (new_allocator.h:86)
==25907==    by 0x804939B: std::_Rb_tree<std::string, std::pair<std::string const, int>, std::_Select1st<std::pair<std::string const, int> >, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::_M_put_node(std::_Rb_tree_node<std::pair<std::string const, int> >*) (stl_tree.h:360)
==25907==    by 0x8049121: std::_Rb_tree<std::string, std::pair<std::string const, int>, std::_Select1st<std::pair<std::string const, int> >, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >::destroy_node(std::_Rb_tree_node<std::pair<std::string const, int> >*) (stl_tree.h:390)

[ etc ]
From: William James
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <gi44ok02usb@enews4.newsguy.com>
Slobodan Blazeski wrote:

> On Dec 14, 12:01�pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
> > Clojure, from what I've gathered, lets one access hash tables just
> > by referring to them in the CAR of an evaluated form:
> > 
> > (defparameter ht (make-hash-table))
> > 
> > (ht 'foo) == (gethash 'foo ht)
> Actually I feel that as too verbose:
> (ht 'foo)
> ->foo-val
> would be even better.

Still too verbose.

JavaScript:

js> h = {foo: 77, bar: 88}
[object Object]
js> h.foo
77
js> h.bar
88

> also I want below too for multiple keys selection:
> (ht '(foo bar baz))
> -> (foo-val bar-val baz-val)

Ruby:

h = {:foo, "foo_val", :bar, "bar_val", :baz, "baz_val"}
    ==>{:baz=>"baz_val", :foo=>"foo_val", :bar=>"bar_val"}
h.values_at( :foo, :bar, :baz )
    ==>["foo_val", "bar_val", "baz_val"]

> and possibly even this:
> (ht (lambda (key) (like (princ-to-string key) "*-bar"))))

h.keys.map{|x| x.to_s}.grep(/^ba/)
    ==>["baz", "bar"]
h.select{|key,val| key.to_s.match(/^ba/) }
    ==>[[:baz, "baz_val"], [:bar, "bar_val"]]
h.values.grep( /^ba/ )
    ==>["baz_val", "bar_val"]
From: Kaz Kylheku
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <20081230145055.102@gmail.com>
On 2008-12-14, William James <·········@yahoo.com> wrote:
> Still too verbose.

Like you.
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <86991aa1-29b3-4205-97ef-ebf8c6601478@r34g2000vbp.googlegroups.com>
I don't like replying to trolls, but since this question is of much
interest to me I'll. Thank you Kaz for making this reply visible to
me.
On Dec 15, 12:27 am, "William James" <·········@yahoo.com> wrote:
> Slobodan Blazeski wrote:
> > On Dec 14, 12:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
> > > Clojure, from what I've gathered, lets one access hash tables just
> > > by referring to them in the CAR of an evaluated form:
>
> > > (defparameter ht (make-hash-table))
>
> > > (ht 'foo) == (gethash 'foo ht)
> > Actually I feel that as too verbose:
> > (ht 'foo)
> > ->foo-val
> > would be even better.
>
> Still too verbose.
>
> JavaScript:
>
> js> h = {foo: 77, bar: 88}
> [object Object]
> js> h.foo
> 77
> js> h.bar
> 88
h.bar  - token count 2

That's slightly better for accessing  a single element, token count is
the same 2 but you don't have to use braces instead have a dot, but
how would you access more elements or use a predicate WITHOUT
breaking the consistency NOR adding new tokens?
>
> > also I want below too for multiple keys selection:
> > (ht '(foo bar baz))
> > -> (foo-val bar-val baz-val)
>
> Ruby:
>
> h = {:foo, "foo_val", :bar, "bar_val", :baz, "baz_val"}
>     ==>{:baz=>"baz_val", :foo=>"foo_val", :bar=>"bar_val"}
> h.values_at( :foo, :bar, :baz )
>     ==>["foo_val", "bar_val", "baz_val"]
This is where your solutions flops. You're unable to access multiple
elements with the dot syntax  so you're forced into adding a function.
h.values_at(...) - 2 tokens just for syntax plus 2 braces ignoring the
keys
(h ...)          - only one token plus 2 braces,ignoring the keys
I win.
>
> > and possibly even this:
> > (ht (lambda (key) (like (princ-to-string key) "*-bar"))))
>
> h.keys.map{|x| x.to_s}.grep(/^ba/)
Lets's see:
h.*VALUES?*.map{predicate}- 3 tokens  plus 2 braces ignoring the
predicate
(h predicate) - 1 token plus 2 braces ignoring the predicate

See your cheap ruby tricks doesn't scale well. You already losing 3:1
Now the real challenge?
Given ht : keys 1 2 3 '(1 2)   :values 1-val 2-val 3-val 1-2-val
(h 1 2 '(1 2) (lambda (x) (and (numberp x) (oddp x))))
-> (1-val 2-val 1-2-val (1-val 3-val))

Your move.

bobi
From: Jochen Schmidt
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <04186325-5a16-46ea-a5fe-5d64a10e0d71@q30g2000prq.googlegroups.com>
On 14 Dez., 12:01, "Leslie P. Polzer" <·············@gmx.net> wrote:
> Clojure, from what I've gathered, lets one access hash tables just by
> referring to them in the CAR of an evaluated form:
>
> (defparameter ht (make-hash-table))
>
> (ht 'foo) == (gethash 'foo ht)
> (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> It should be easy to emulate the hash table reader at least in
> function context, by defining a custom DEFUN-wrapping macro that
> dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> Is this also possible for the SETF expansion? I think it should be,
> but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
>   Leslie

It's not that easy. The problem is, that there is no way to override
the syntax of a cl funtion call. You can either have a symbol denoting
a function or a lambda expression. You can extend the function call
protocol though: By implementing an hashtable or array as a
funcallable-instance. You could then use FUNCALL on the hashtable:

(funcall *ht* 1)

The missing part could be a macro which enables writing single-
namespace lisp code:

(defmacro with-single-namespace ((&rest fns) &body forms)
   `(macrolet (,@(mapcar (lambda (fn) `(,fn (&rest args)
                                       `(funcall ,',fn ,@,'args)))
fns))
                  ,@forms))

(with-single-namespace (*ht*)
  (+ (*ht* 1) (*ht* 2)))

-> (+ (funcall *ht* 1) (funcall *ht* 2))

Another solution could be:

(defmacro with-hashtables ((&rest hts) &body forms)
  `(macrolet (,@(mapcar (lambda (ht) `(,ht (key)
                                        `(gethash ,,'key ,',ht)))
hts))
     ,@forms))

(defmacro with-arrays ((&rest as) &body forms)
   `(macrolet (,@(mapcar (lambda (a) `(,a (&rest args)
                                       `(aref ,',a ,@,'args))) as))
                  ,@forms))

Or as generalization of this:

(defmacro with-collections ((&rest cs) &body forms)
   `(macrolet (,@(mapcar (lambda (c) `(,c (&rest args)
                                       `(element ,',c ,@,'args)))
cs))
                  ,@forms))

(defmethod element ((ht hash-table) &rest keys)
  (if (rest keys)
    (apply #'element (gethash (first keys) ht) (rest keys))
  (gethash (first keys) ht)))

(defmethod element ((a array) &rest keys)
  (apply #'aref a keys))

(defun alist->ht (alist &key (test 'eql))
  (loop with ht = (make-hash-table :test test)
        for (key . value) in alist do (setf (gethash key ht) value)
        finally (return ht)))

(defun plist->ht (plist &key (test 'eql))
  (loop with ht = (make-hash-table :test test)
        for (key value) on plist by #'cddr do (setf (gethash key ht)
value)
        finally (return ht)))

(let ((ht (alist->ht `((a . ,(alist->ht '((1 . "Foo")(2 . "Bar")(3 .
"Baz"))))
                       (b . ,(alist->ht '((1 . "FOO")(2 . "BAR")(3 .
"BAZ")))))))
      (a #(a b c d e f))
      (mix (plist->ht `(a #(p q r) b #(x y z)))))
  (with-collections (ht a mix) (values (ht 'b 3) (a 2) (mix 'b 1))))

==>
"BAZ"
C
Y

--
Jochen Schmidt
CRISPYLOGICS
Uhlandstr. 9, 90408 Nuremberg

Fon +49 (0)911 517 999 82
Fax +49 (0)911 517 999 83

mailto:(format nil "~(····@~36r.~36r~)" 870180 1680085828711918828
16438) http://www.crispylogics.com
From: Leslie P. Polzer
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <79727957-cc4c-40b0-842d-8a07646c6868@x16g2000prn.googlegroups.com>
On Dec 14, 3:07 pm, Jochen Schmidt <····@crispylogics.com> wrote:

> It's not that easy. The problem is, that there is no way to override
> the syntax of a cl funtion call. You can either have a symbol denoting
> a function or a lambda expression.

Why not?

Consider a syntax transformation via code walker that does something
like

  (fn-or-ht arg)

  =>

  (if (typep fn-or-ht 'hash-table)
     (gethash fn-or-ht arg)
     (funcall fn-or-ht arg))
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-3895B8.19212214122008@news-europe.giganews.com>
In article 
<····································@x16g2000prn.googlegroups.com>,
 "Leslie P. Polzer" <·············@gmx.net> wrote:

> On Dec 14, 3:07�pm, Jochen Schmidt <····@crispylogics.com> wrote:
> 
> > It's not that easy. The problem is, that there is no way to override
> > the syntax of a cl funtion call. You can either have a symbol denoting
> > a function or a lambda expression.
> 
> Why not?
> 
> Consider a syntax transformation via code walker that does something
> like
> 
>   (fn-or-ht arg)
> 
>   =>
> 
>   (if (typep fn-or-ht 'hash-table)
>      (gethash fn-or-ht arg)
>      (funcall fn-or-ht arg))

CL-USER 4 > (flet ((fn-or-ht (foo) foo))
  (if (typep fn-or-ht 'hash-table) 
      (gethash fn-or-ht arg) 
    (funcall fn-or-ht arg)))

Error: The variable FN-OR-HT is unbound.
  1 (continue) Try evaluating FN-OR-HT again.
  2 Specify a value to use this time instead of evaluating FN-OR-HT.
  3 Specify a value to set FN-OR-HT to.
  4 (abort) Return to level 0.
  5 Return to top loop level 0.

Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.

CL-USER 5 : 1 > :top

CL-USER 6 > (flet ((fn-or-ht (foo) foo))
  (if (typep fn-or-ht 'hash-table) 
      (gethash fn-or-ht arg) 
    (funcall (function fn-or-ht) arg)))

Error: The variable FN-OR-HT is unbound.
  1 (continue) Try evaluating FN-OR-HT again.
  2 Specify a value to use this time instead of evaluating FN-OR-HT.
  3 Specify a value to set FN-OR-HT to.
  4 (abort) Return to level 0.
  5 Return to top loop level 0.

Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.

CL-USER 7 : 1 >

-- 
http://lispm.dyndns.org/
From: Leslie P. Polzer
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <a0ace9c5-f068-43df-9b55-a297b26463b6@a26g2000prf.googlegroups.com>
On Dec 14, 7:21 pm, Rainer Joswig <······@lisp.de> wrote:
>
> Error: The variable FN-OR-HT is unbound.

CL-USER(36): (defmacro with-hts (form)
  `(if (and (boundp ',(car form)) (typep ,(car form) 'hash-table))
     (gethash ,(cadr form) (symbol-value (find-symbol ,(princ-to-
string (car form)) *package*)))
     (funcall ',(car form) ,(cadr form))))

WITH-HTS
CL-USER(37): (defparameter ht (make-hash-table))

HT
CL-USER(39): (setf (gethash 2 ht) t)

T
CL-USER(40): (with-hts (ht 2))

T
T
CL-USER(41): (with-hts (ht 1))

NIL
NIL
CL-USER(42): (with-hts (identity 1))

1

This is what I had in mind.

I know it doesn't work with hash tables from other packages, but it's
just a demo.
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-71B4D7.11572515122008@news-europe.giganews.com>
In article 
<····································@a26g2000prf.googlegroups.com>,
 "Leslie P. Polzer" <·············@gmx.net> wrote:

> On Dec 14, 7:21�pm, Rainer Joswig <······@lisp.de> wrote:
> >
> > Error: The variable FN-OR-HT is unbound.
> 
> CL-USER(36): (defmacro with-hts (form)
>   `(if (and (boundp ',(car form)) (typep ,(car form) 'hash-table))
>      (gethash ,(cadr form) (symbol-value (find-symbol ,(princ-to-
> string (car form)) *package*)))
>      (funcall ',(car form) ,(cadr form))))


Sorry, but above looks seriously confused.

Can you explain why you are expanding into using a FIND-SYMBOL?

You check on boundp on a possibly local variable, but
then you take the value from a SYMBOL? Those are
two different things. It can very well be that
the variable is bound, but the symbol has no value.

You also try to call a function value of a symbol?
Why?


CL-USER 30 > (let ((h1 (make-hash-table))) (with-hts (h1 2)))

Error: Undefined function H1 called with arguments (2).
  1 (continue) Try invoking H1 again.


Also adding runtime checks and special code for various
Lisp data types makes the compiled code bloated, slow, ...
I don't like that way...

> 
> WITH-HTS
> CL-USER(37): (defparameter ht (make-hash-table))
> 
> HT
> CL-USER(39): (setf (gethash 2 ht) t)
> 
> T
> CL-USER(40): (with-hts (ht 2))
> 
> T
> T
> CL-USER(41): (with-hts (ht 1))
> 
> NIL
> NIL
> CL-USER(42): (with-hts (identity 1))
> 
> 1
> 
> This is what I had in mind.
> 
> I know it doesn't work with hash tables from other packages, but it's
> just a demo.

I don't think simple demos are a good way to demonstrate whether
the approach would make sense for Common Lisp.

-- 
http://lispm.dyndns.org/
From: Leslie P. Polzer
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <0ec71c30-91ba-4f2f-a9e5-28666778e1c2@s1g2000prg.googlegroups.com>
On Dec 15, 11:57 am, Rainer Joswig <······@lisp.de> wrote:

> I don't think simple demos are a good way to demonstrate whether
> the approach would make sense for Common Lisp.

That was not the point I wanted to make.

I'm fine with GETHASH personally, but I was interested in whether
CL would be capable of emulating this syntax.

About the runtime checking -- yes, sure it is expensive.

How does Clojure do it?
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-89F35F.13260415122008@news-europe.giganews.com>
In article 
<····································@s1g2000prg.googlegroups.com>,
 "Leslie P. Polzer" <·············@gmx.net> wrote:

> On Dec 15, 11:57�am, Rainer Joswig <······@lisp.de> wrote:
> 
> > I don't think simple demos are a good way to demonstrate whether
> > the approach would make sense for Common Lisp.
> 
> That was not the point I wanted to make.
> 
> I'm fine with GETHASH personally, but I was interested in whether
> CL would be capable of emulating this syntax.

I have never tried to implement it, but I guess one
can get quite far with added runtime checks through
macros, code walking and the like. But the result will
not be pretty.

Common Lisp has been designed with the goal to be efficient
on stock hardware. That was a goal at a time when
there was also special Lisp hardware. On a Lisp
Machine the function call mechanism was coded in
microcode. This was extensible via new microcode versions.
On a Lisp Machine I can push a string on the
stack and call it. Means this is even built into
the microcode of the CPU.

But Common Lisp was thought with a compiler
for all kinds of CPUs in mind.

For example (foo 3) will not need a runtime
check whether foo is a function or something else. FOO can never be
anything else than: a function or undefined.
The compiler can make a few assumptions when compiling
a file. There is no basic mechanism in the language
that extends a) the number of allowed basic
syntactic constructs (function calls, lambda calls, special forms, macros)
or b) the number of basic function types. The latter
had to be extended from CLtL1 to ANSI CL with
funcallable objects, because there was no mechanism
to add those to the language by the user.

So you can't do

CL-USER 33 > (setf (symbol-function 'foobar) (make-hash-table))

Error: Setting symbol-function of FOOBAR to incorrect value #<EQL Hash Table{0} 402000387B>.

and add some magic to make a hash-table be interpreted as kind
of a function.

There are normal values and functional values. The functional
values are all functions (normal functions, generic functions).
There is no way to add anything else in the base language.

So hash-tables are normal values and not functional values.
Common Lisp is a Lisp-2 and functions have their own namespace.
If you now would want that Common Lisp uses values from
the value space as functions, then there are built-in forms
to do that: FUNCALL calls a value as a function. FUNCTION
gets a function from the function space and returns it
as a value. Those are not extensible.

So, the function types, the basic syntax and the mechanims
to call functions or retrieve functions are built into
the language and are not extensible (other than
creating new subclasses for funcallable objects).

The only way to deal with that is at the reader or
macro level and create special code. But that's ugly.

For me there are style rules:

a) stay within the basic mechanisms of the language
   for any software that one likes to write in Common Lisp

b) if there is a language built on top of Common Lisp
   that wants to do something different, then fine, but
   one has to consider the implementation costs.

c) if one wants to experiment and propose future
   extensions or wants to create a new dialect. Fine.

Even though Common Lisp is a large language, the number of core
principles is not THAT large (there is a lot
of what is in ANSI CL more like library functionality).
It is in this respect a bit different from languages
that want to be more pragmatic for the programmer
and provide all kind of ad-hoc mechanisms that the
language designer liked. The benefit is that Common Lisp
is compilable to efficient code. The cost is that
not everything that may look convenient for programmers
(FEXPRs, ...) is available.

> 
> About the runtime checking -- yes, sure it is expensive.
> 
> How does Clojure do it?

I have no idea. But I would guess it is built into
the language.

-- 
http://lispm.dyndns.org/
From: Rich Hickey
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4fafe852-ef4d-44f8-8962-29c7d621f133@n28g2000vba.googlegroups.com>
On Dec 15, 7:26 am, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@s1g2000prg.googlegroups.com>,
>  "Leslie P. Polzer" <·············@gmx.net> wrote:
>
> > On Dec 15, 11:57 am, Rainer Joswig <······@lisp.de> wrote:

> > About the runtime checking -- yes, sure it is expensive.
>
> > How does Clojure do it?
>
> I have no idea. But I would guess it is built into
> the language.
>

The underpinnings of all of Clojure's abstractions, including
callability in this case, have corresponding Java interfaces. This
allows for multiple implementations and high-performance dispatch.

There is an interface, IFn, that defines callability, and anything
that implements it (function objects obviously, but also associative
collections) is callable. The cost of a call is the cost of an
ordinary Java virtual method call - they are plenty fast.

So, while "only IFns are callable" is built into Clojure, the set of
callable things is open - just implement IFn, either in Clojure or
Java.

That said, callability can't be extended to any arbitrary type - for
instance there is no way to make Strings or Numbers callable (if that
made sense) since their types are closed.

This seems, to me, a fair compromise between extensibility and
performance, leveraging the high-performance dispatch of the host VM
substrate, and is the model used throughout Clojure.

Rich
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-65BFDC.14422215122008@news-europe.giganews.com>
In article 
<····································@n28g2000vba.googlegroups.com>,
 Rich Hickey <··········@gmail.com> wrote:

> On Dec 15, 7:26 am, Rainer Joswig <······@lisp.de> wrote:
> > In article
> > <····································@s1g2000prg.googlegroups.com>,
> >  "Leslie P. Polzer" <·············@gmx.net> wrote:
> >
> > > On Dec 15, 11:57 am, Rainer Joswig <······@lisp.de> wrote:
> 
> > > About the runtime checking -- yes, sure it is expensive.
> >
> > > How does Clojure do it?
> >
> > I have no idea. But I would guess it is built into
> > the language.
> >
> 
> The underpinnings of all of Clojure's abstractions, including
> callability in this case, have corresponding Java interfaces. This
> allows for multiple implementations and high-performance dispatch.
> 
> There is an interface, IFn, that defines callability, and anything
> that implements it (function objects obviously, but also associative
> collections) is callable. The cost of a call is the cost of an
> ordinary Java virtual method call - they are plenty fast.
> 
> So, while "only IFns are callable" is built into Clojure, the set of
> callable things is open - just implement IFn, either in Clojure or
> Java.
> 
> That said, callability can't be extended to any arbitrary type - for
> instance there is no way to make Strings or Numbers callable (if that
> made sense) since their types are closed.

Numbers, I don't know. Maybe access digits or bytes
from an integer?

But strings, sure. If you like callable data,

then  (let ((a "123"))  (a 1))   makes sense.

But I'm not a fan of anything like that. I like to see
the operations as names in the source code. I don't
like to infer from the context what is going on
even for primitive sources. I also don't like to
look in a debugger at stack frames that have data
objects in its functional position. Maybe that's just me.

> 
> This seems, to me, a fair compromise between extensibility and
> performance, leveraging the high-performance dispatch of the host VM
> substrate, and is the model used throughout Clojure.
> 
> Rich

-- 
http://lispm.dyndns.org/
From: Pascal J. Bourguignon
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <7cabaxctof.fsf@pbourguignon.anevia.com>
Rainer Joswig <······@lisp.de> writes:

> In article 
> <····································@n28g2000vba.googlegroups.com>,
>  Rich Hickey <··········@gmail.com> wrote:
>
>> On Dec 15, 7:26 am, Rainer Joswig <······@lisp.de> wrote:
>> > In article
>> > <····································@s1g2000prg.googlegroups.com>,
>> >  "Leslie P. Polzer" <·············@gmx.net> wrote:
>> >
>> > > On Dec 15, 11:57 am, Rainer Joswig <······@lisp.de> wrote:
>> 
>> > > About the runtime checking -- yes, sure it is expensive.
>> >
>> > > How does Clojure do it?
>> >
>> > I have no idea. But I would guess it is built into
>> > the language.
>> >
>> 
>> The underpinnings of all of Clojure's abstractions, including
>> callability in this case, have corresponding Java interfaces. This
>> allows for multiple implementations and high-performance dispatch.
>> 
>> There is an interface, IFn, that defines callability, and anything
>> that implements it (function objects obviously, but also associative
>> collections) is callable. The cost of a call is the cost of an
>> ordinary Java virtual method call - they are plenty fast.
>> 
>> So, while "only IFns are callable" is built into Clojure, the set of
>> callable things is open - just implement IFn, either in Clojure or
>> Java.
>> 
>> That said, callability can't be extended to any arbitrary type - for
>> instance there is no way to make Strings or Numbers callable (if that
>> made sense) since their types are closed.
>
> Numbers, I don't know. Maybe access digits or bytes
> from an integer?
>
> But strings, sure. If you like callable data,
>
> then  (let ((a "123"))  (a 1))   makes sense.
>
> But I'm not a fan of anything like that. I like to see
> the operations as names in the source code. I don't
> like to infer from the context what is going on
> even for primitive sources. I also don't like to
> look in a debugger at stack frames that have data
> objects in its functional position. Maybe that's just me.

I agree, it's a strong point of lisp, having an explicit operator
and uniform form: (operator args...).

However, seeking sequences and hash-tables are mappings, that is
functions, can be practical.  You can do it nicely in CL:

(let ((a "123"))
  (flet ((a (index) (aref a index)))
    (a 1)))
 --> #\2

And as always, if you do that a lot, you introduce a macro:

(with-map-function ((seq  "123")
                    (hash (hash-table (:one . "un") (:two . "deux") (:three . "trois"))))
   (list seq (seq 1) hash (hash :two)))
--> ("123" #\2 #S(HASH-TABLE :TEST EXT:FASTHASH-EQL (:THREE . "trois") (:TWO . "deux") (:ONE . "un")) "deux")

-- 
__Pascal Bourguignon__
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-206E46.17375315122008@news-europe.giganews.com>
In article <··············@pbourguignon.anevia.com>,
 ···@informatimago.com (Pascal J. Bourguignon) wrote:

> Rainer Joswig <······@lisp.de> writes:
> 
> > In article 
> > <····································@n28g2000vba.googlegroups.com>,
> >  Rich Hickey <··········@gmail.com> wrote:
> >
> >> On Dec 15, 7:26 am, Rainer Joswig <······@lisp.de> wrote:
> >> > In article
> >> > <····································@s1g2000prg.googlegroups.com>,
> >> >  "Leslie P. Polzer" <·············@gmx.net> wrote:
> >> >
> >> > > On Dec 15, 11:57 am, Rainer Joswig <······@lisp.de> wrote:
> >> 
> >> > > About the runtime checking -- yes, sure it is expensive.
> >> >
> >> > > How does Clojure do it?
> >> >
> >> > I have no idea. But I would guess it is built into
> >> > the language.
> >> >
> >> 
> >> The underpinnings of all of Clojure's abstractions, including
> >> callability in this case, have corresponding Java interfaces. This
> >> allows for multiple implementations and high-performance dispatch.
> >> 
> >> There is an interface, IFn, that defines callability, and anything
> >> that implements it (function objects obviously, but also associative
> >> collections) is callable. The cost of a call is the cost of an
> >> ordinary Java virtual method call - they are plenty fast.
> >> 
> >> So, while "only IFns are callable" is built into Clojure, the set of
> >> callable things is open - just implement IFn, either in Clojure or
> >> Java.
> >> 
> >> That said, callability can't be extended to any arbitrary type - for
> >> instance there is no way to make Strings or Numbers callable (if that
> >> made sense) since their types are closed.
> >
> > Numbers, I don't know. Maybe access digits or bytes
> > from an integer?
> >
> > But strings, sure. If you like callable data,
> >
> > then  (let ((a "123"))  (a 1))   makes sense.
> >
> > But I'm not a fan of anything like that. I like to see
> > the operations as names in the source code. I don't
> > like to infer from the context what is going on
> > even for primitive sources. I also don't like to
> > look in a debugger at stack frames that have data
> > objects in its functional position. Maybe that's just me.
> 
> I agree, it's a strong point of lisp, having an explicit operator
> and uniform form: (operator args...).

I like the usual (Common) Lisp syntax because it follows some
principles that I find useful. What I don't find useful is
encoding operators by whitespace or even by less than
whitespace.

> However, seeking sequences and hash-tables are mappings, that is
> functions, can be practical.  You can do it nicely in CL:
> 
> (let ((a "123"))
>   (flet ((a (index) (aref a index)))
>     (a 1)))
>  --> #\2

Sure, but I would ask: what is the principle behind that? When and why does it make
sense?

I would introduce a function

* when I want to hide the implementation

* when I want to do some computation and want to do something with the
  data key behind the scenes

(defun get-frame-named (name &optional (storage *default-frame-hash-table*))
  (gethash storage (find-symbol (format nil "FRAME-~a" name))))

Now I could make that more generic:

(defun get-frame-named (name &optional (storage *default-storage*))
  (table-get storage (find-symbol (format nil "FRAME-~a" name))))

Now I could have funcallable tables (think STORAGE gets some kind of table object):

(defun get-frame-named (name &optional (storage *default-storage*))
  (storage (find-symbol (format nil "FRAME-~a" name))))

Do I really want to blur functions and variables?
Seeing stuff like that in libraries would puzzle me and
it helps creating maintenance problems.

In the source code I can ask the editor to find the location of the operation
of TABLE-GET. But in the third case STORAGE is just a local variable.
How do I find what it does?

> 
> And as always, if you do that a lot, you introduce a macro:
> 
> (with-map-function ((seq  "123")
>                     (hash (hash-table (:one . "un") (:two . "deux") (:three . "trois"))))
>    (list seq (seq 1) hash (hash :two)))
> --> ("123" #\2 #S(HASH-TABLE :TEST EXT:FASTHASH-EQL (:THREE . "trois") (:TWO . "deux") (:ONE . "un")) "deux")

-- 
http://lispm.dyndns.org/
From: ··················@gmail.com
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <3966ddaf-435f-4341-aea8-590768bfdc80@w39g2000prb.googlegroups.com>
Could write a macro to define a function with the same name as the
hash table,
then write a defsetf or def-setf-method for the function, so that it
updates the hash table.

something like this (not completed)

(defmacro def-hash (symbol)
  `(progn
     (defvar ,symbol nil)
     (setf ,symbol (make-hash-table))
     (defun ,symbol (&rest hash-keys)
       (let ((list nil))
	 (dolist (hash-key hash-keys)
	   (push (gethash hash-key ,symbol) list))
	 (reverse list)))

     (defsetf ,symbol [defsetf stuff here]...
)))

would pretty much duplicate the behavior of clojure once you got it
working.
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-9B8FC6.18242615122008@news-europe.giganews.com>
In article 
<····································@w39g2000prb.googlegroups.com>,
 ··················@gmail.com wrote:

> Could write a macro to define a function with the same name as the
> hash table,
> then write a defsetf or def-setf-method for the function, so that it
> updates the hash table.
> 
> something like this (not completed)
> 
> (defmacro def-hash (symbol)
>   `(progn
>      (defvar ,symbol nil)
>      (setf ,symbol (make-hash-table))
>      (defun ,symbol (&rest hash-keys)
>        (let ((list nil))
> 	 (dolist (hash-key hash-keys)
> 	   (push (gethash hash-key ,symbol) list))
> 	 (reverse list)))

That also looks ugly. Why would I use such a thing?
It does not work for local variables.
I introduces a global variable and a global function.
(foo 'bar) now returns a list? 
GETHASH returns two values, one is now gone.

In German we call that 'Verschlimmbesserung'.

> 
>      (defsetf ,symbol [defsetf stuff here]...
> )))
> 
> would pretty much duplicate the behavior of clojure once you got it
> working.

-- 
http://lispm.dyndns.org/
From: ··················@gmail.com
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <dd6b823e-b69b-4990-b29a-339c8659e868@d42g2000prb.googlegroups.com>
On Dec 15, 12:24 pm, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@w39g2000prb.googlegroups.com>,
>
>
>
>  ··················@gmail.com wrote:
> > Could write a macro to define a function with the same name as the
> > hash table,
> > then write a defsetf or def-setf-method for the function, so that it
> > updates the hash table.
>
> > something like this (not completed)
>
> > (defmacro def-hash (symbol)
> >   `(progn
> >      (defvar ,symbol nil)
> >      (setf ,symbol (make-hash-table))
> >      (defun ,symbol (&rest hash-keys)
> >        (let ((list nil))
> >     (dolist (hash-key hash-keys)
> >       (push (gethash hash-key ,symbol) list))
> >     (reverse list)))
>
> That also looks ugly. Why would I use such a thing?
> It does not work for local variables.
> I introduces a global variable and a global function.
> (foo 'bar) now returns a list?
> GETHASH returns two values, one is now gone.
>
> In German we call that 'Verschlimmbesserung'.
>
>
>
> >      (defsetf ,symbol [defsetf stuff here]...
> > )))
>
> > would pretty much duplicate the behavior of clojure once you got it
> > working.
>
> --http://lispm.dyndns.org/

Is a proof of concept and not a final solution. That you are stupid
and don't know how to apply the concept is not my problem.
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-4EB487.20080515122008@news-europe.giganews.com>
In article 
<····································@d42g2000prb.googlegroups.com>,
 ··················@gmail.com wrote:

> On Dec 15, 12:24�pm, Rainer Joswig <······@lisp.de> wrote:
> > In article
> > <····································@w39g2000prb.googlegroups.com>,
> >
> >
> >
> > ···················@gmail.com wrote:
> > > Could write a macro to define a function with the same name as the
> > > hash table,
> > > then write a defsetf or def-setf-method for the function, so that it
> > > updates the hash table.
> >
> > > something like this (not completed)
> >
> > > (defmacro def-hash (symbol)
> > > � `(progn
> > > � � �(defvar ,symbol nil)
> > > � � �(setf ,symbol (make-hash-table))
> > > � � �(defun ,symbol (&rest hash-keys)
> > > � � � �(let ((list nil))
> > > � � (dolist (hash-key hash-keys)
> > > � � � (push (gethash hash-key ,symbol) list))
> > > � � (reverse list)))
> >
> > That also looks ugly. Why would I use such a thing?
> > It does not work for local variables.
> > I introduces a global variable and a global function.
> > (foo 'bar) now returns a list?
> > GETHASH returns two values, one is now gone.
> >
> > In German we call that 'Verschlimmbesserung'.
> >
> >
> >
> > > � � �(defsetf ,symbol [defsetf stuff here]...
> > > )))
> >
> > > would pretty much duplicate the behavior of clojure once you got it
> > > working.
> >
> > --http://lispm.dyndns.org/
> 
> Is a proof of concept and not a final solution. That you are stupid
> and don't know how to apply the concept is not my problem.

Sure I am stupid and you are now in my killfile.

-- 
http://lispm.dyndns.org/
From: ··················@gmail.com
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <d095356d-cc50-41c9-a375-fe534d900cc6@n33g2000pri.googlegroups.com>
On Dec 15, 2:08 pm, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@d42g2000prb.googlegroups.com>,
>
>
>
>  ··················@gmail.com wrote:
> > On Dec 15, 12:24 pm, Rainer Joswig <······@lisp.de> wrote:
> > > In article
> > > <····································@w39g2000prb.googlegroups.com>,
>
> > >  ··················@gmail.com wrote:
> > > > Could write a macro to define a function with the same name as the
> > > > hash table,
> > > > then write a defsetf or def-setf-method for the function, so that it
> > > > updates the hash table.
>
> > > > something like this (not completed)
>
> > > > (defmacro def-hash (symbol)
> > > >   `(progn
> > > >      (defvar ,symbol nil)
> > > >      (setf ,symbol (make-hash-table))
> > > >      (defun ,symbol (&rest hash-keys)
> > > >        (let ((list nil))
> > > >     (dolist (hash-key hash-keys)
> > > >       (push (gethash hash-key ,symbol) list))
> > > >     (reverse list)))
>
> > > That also looks ugly. Why would I use such a thing?
> > > It does not work for local variables.
> > > I introduces a global variable and a global function.
> > > (foo 'bar) now returns a list?
> > > GETHASH returns two values, one is now gone.
>
> > > In German we call that 'Verschlimmbesserung'.
>
> > > >      (defsetf ,symbol [defsetf stuff here]...
> > > > )))
>
> > > > would pretty much duplicate the behavior of clojure once you got it
> > > > working.
>
> > > --http://lispm.dyndns.org/
>
> > Is a proof of concept and not a final solution. That you are stupid
> > and don't know how to apply the concept is not my problem.
>
> Sure I am stupid and you are now in my killfile.
>
> --http://lispm.dyndns.org/

The fact of the matter is that it would work equally well using let
and flet (or using some of the lower level binding stuff) as it would
using defvar and defun, and could be made to return both the key and
stored-value.

'Something like' means 'something like' not 'THIS IS EXACTLY HOW I
WOULD IMPLEMENT IT'.

Ranier:
You made some fairly trivial complaints about the hackish
implementation, missed the point entirely, and weren't terribly nice
about it. What type of response did you expect?  Not that you'll ever
read this.
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4946a27a$0$90265$14726298@news.sunsite.dk>
 LPP> How does Clojure do it?

by being "Lisp-1", duh. when there is single namespace, you do not need any
runtime logic to check if thingie is a function or a hashtable.

 RH> There is an interface, IFn, that defines callability, and anything
 RH> that implements it (function objects obviously, but also associative
 RH> collections) is callable.

it's pretty easy to do it in Common Lisp via funcallable-standard-object
and friends: this way you can create an object that sort of "implements IFn 
interface"
and is accessible by other means as well.

the only issue is namespace quantity. 
From: ······@corporate-world.lisp.de
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <56e2f5b1-0870-4c1a-9578-f2986a9fb7e2@o40g2000prn.googlegroups.com>
On 15 Dez., 19:31, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  LPP> How does Clojure do it?
>
> by being "Lisp-1", duh. when there is single namespace, you do not need any
> runtime logic to check if thingie is a function or a hashtable.

So, how do you get Clojure to accept strings in function position?
("abc" 1)

and

(let ((s "abc"))     ; whatever the LET syntax is for Clojure
  (s 1))

(let ((s "abc") (i 1))     ; whatever the LET syntax is for Clojure
  (s i))


Without runtime checks, please.

>
>  RH> There is an interface, IFn, that defines callability, and anything
>  RH> that implements it (function objects obviously, but also associative
>  RH> collections) is callable.
>
> it's pretty easy to do it in Common Lisp via funcallable-standard-object
> and friends: this way you can create an object that sort of "implements IFn
> interface"
> and is accessible by other means as well.
>
> the only issue is namespace quantity.
From: Rich Hickey
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <19636c0a-3444-4e95-84f9-33f82617940f@k36g2000yqe.googlegroups.com>
On Dec 16, 6:45 am, ·······@corporate-world.lisp.de" <······@corporate-
world.lisp.de> wrote:
> On 15 Dez., 19:31, "Alex Mizrahi" <········@users.sourceforge.net>
> wrote:
>
> >  LPP> How does Clojure do it?
>
> > by being "Lisp-1", duh. when there is single namespace, you do not need any
> > runtime logic to check if thingie is a function or a hashtable.
>
> So, how do you get Clojure to accept strings in function position?
> ("abc" 1)
>

You don't:

http://groups.google.com/group/comp.lang.lisp/msg/14b3d82313b0bc8d

Rich
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-5C41C6.13441216122008@news-europe.giganews.com>
In article 
<····································@k36g2000yqe.googlegroups.com>,
 Rich Hickey <··········@gmail.com> wrote:

> On Dec 16, 6:45 am, ·······@corporate-world.lisp.de" <······@corporate-
> world.lisp.de> wrote:
> > On 15 Dez., 19:31, "Alex Mizrahi" <········@users.sourceforge.net>
> > wrote:
> >
> > >  LPP> How does Clojure do it?
> >
> > > by being "Lisp-1", duh. when there is single namespace, you do not need any
> > > runtime logic to check if thingie is a function or a hashtable.
> >
> > So, how do you get Clojure to accept strings in function position?
> > ("abc" 1)
> >
> 
> You don't:
> 
> http://groups.google.com/group/comp.lang.lisp/msg/14b3d82313b0bc8d
> 
> Rich

Thanks, I read that.

Somehow either the runtime must check if something
is data and call the appropriate functionality.
In case of Clojure there is built-in support
for 'objects' but not for strings. Common Lisp
does not offer that much here. It offers to
call funcallable objects which have a global
name or to use FUNCALL with funcallable objects.

If the runtime does not check that, then the user must
insert runtime checks via whatever mechanism the
language supports, for example via code walking
with a macro. That still holds for a Lisp-1.
For Common Lisp this is even more difficult. It is
a Lisp-2 and accepts only functions in the function
namespace. Values from the value space can only
be called via FUNCALL.

So, Alex, a Lisp-1 does not magically get away with
runtime checks. The hashtable feature is built
into the Clojure implementation and is independent
of Clojure being a Lisp-1.

-- 
http://lispm.dyndns.org/
From: Slobodan Blazeski
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <6ea7781d-c7ac-4751-b40c-2773533e48f4@x16g2000prn.googlegroups.com>
On Dec 16, 1:44 pm, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@k36g2000yqe.googlegroups.com>,
>  Rich Hickey <··········@gmail.com> wrote:
>
>
>
> > On Dec 16, 6:45 am, ·······@corporate-world.lisp.de" <······@corporate-
> > world.lisp.de> wrote:
> > > On 15 Dez., 19:31, "Alex Mizrahi" <········@users.sourceforge.net>
> > > wrote:
>
> > > >  LPP> How does Clojure do it?
>
> > > > by being "Lisp-1", duh. when there is single namespace, you do not need any
> > > > runtime logic to check if thingie is a function or a hashtable.
>
> > > So, how do you get Clojure to accept strings in function position?
> > > ("abc" 1)
>
> > You don't:
>
> >http://groups.google.com/group/comp.lang.lisp/msg/14b3d82313b0bc8d
>
> > Rich
>
> Thanks, I read that.
>
> Somehow either the runtime must check if something
> is data and call the appropriate functionality.
> In case of Clojure there is built-in support
> for 'objects' but not for strings. Common Lisp
> does not offer that much here. It offers to
> call funcallable objects which have a global
> name or to use FUNCALL with funcallable objects.
>
> If the runtime does not check that, then the user must
> insert runtime checks via whatever mechanism the
> language supports, for example via code walking
> with a macro. That still holds for a Lisp-1.
> For Common Lisp this is even more difficult. It is
> a Lisp-2 and accepts only functions in the function
> namespace. Values from the value space can only
> be called via FUNCALL.
>
> So, Alex, a Lisp-1 does not magically get away with
> runtime checks. The hashtable feature is built
> into the Clojure implementation and is independent
> of Clojure being a Lisp-1.
>
> --http://lispm.dyndns.org/
Under certain circumstances smart compiler would remove many runtime
checks, but that's just an optimization technique. Computers are
becoming faster and faster so unless you do some heavy number
crunching who cares is some functions finishes in 0.0001 seconds or
magnitude slower? Most of the time application will be spending
waiting for user input, database connection or slow network. And if it
really matters you could always code some part in c (with ffi)  or
even in assembly.

bobi
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4947f43c$0$90276$14726298@news.sunsite.dk>
 RJ> So, Alex, a Lisp-1 does not magically get away with
 RJ> runtime checks.
 RJ>  The hashtable feature is built into the Clojure implementation and is
 RJ> independent of Clojure being a Lisp-1.

adding such functionality is almost trivial in a language which is
Lisp-1 and has funcallable objects (*). either language implementors
or users themselves can just create funcallable objects of a new kind,
and it will just work, reusing core language functionality. no additional
checks are needed.

particularly, if we had language Common Lisp-1, that is sort of identical
to Common Lisp but has single namespace, it would be trivial to add such
functionality via funcallable-standard-object (well, it is sort of 
extension,
but a widespread one).

but it is not possible to make it in Common Lisp. so, obviously, this 
feature
has something to do with Lisp-1.

*: if it does not have funcallable objects, you can make it via plain 
functions.
From: Kaz Kylheku
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <20090101173411.975@gmail.com>
On 2008-12-16, Alex Mizrahi <········@users.sourceforge.net> wrote:
>  RJ> So, Alex, a Lisp-1 does not magically get away with
>  RJ> runtime checks.
>  RJ>  The hashtable feature is built into the Clojure implementation and is
>  RJ> independent of Clojure being a Lisp-1.
>
> adding such functionality is almost trivial in a language which is
> Lisp-1 and has funcallable objects (*). either language implementors
> or users themselves can just create funcallable objects of a new kind,
> and it will just work, reusing core language functionality. no additional
> checks are needed.
>
> particularly, if we had language Common Lisp-1, that is sort of identical
> to Common Lisp but has single namespace, it would be trivial to add such
> functionality via funcallable-standard-object (well, it is sort of 
> extension,
> but a widespread one).
>
> but it is not possible to make it in Common Lisp. so, obviously, this 
> feature
> has something to do with Lisp-1.

What???

Note that when you call

 (funcall X ...)

It's no longer a Lisp-1 versus Lisp-2 issue, since the X being called is in the
second position.

Now in Common Lisp, X has to be a variable, or symbol macro, which ultimately
designates a function object. 

There is no reason why the behavior can't be extended to allow other kinds of
objects to serve as functions.

The dual namespace just means that you have to use funcall for those objects.

If you want to be able to use named objects other than functions, and also
literal objects, in the CAR position, then you need an appropriate extension
for that. E.g. funcallable arrays:

  (let ((a (vector 1 2 3)))
     (funcall a 0) ;; through variable, semantic extension
     (#(1 2 3) 0)) ;; through literal, requires syntactic extension

You could also allow an extension that would allow funcallable objects
other than functions to be installed under function bindings.

E.g. 

   (letf ((a #(1 2 3))) ;; not to be confused with flet
    (a 0) ;; a is true Lisp-2 function binding
    (a a) ;; error in second position, a is unbound.
    (list #'a)) ;; (FUNCTION A) retrieves the vector!!!

If you allow funcallable objects in a Lisp-2, this practically screams
for binding constructs like LETF, and also global defining constructs,
like

  ;; evaluate (vector 1 2 3) and store in function binding of A.
  (defunvar a (vector 1 2 3))

Maybe not trivial, but trivially conceivable. :)
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4948ce56$0$90274$14726298@news.sunsite.dk>
 KK> What???

 KK> Note that when you call

 KK>  (funcall X ...)

 KK> It's no longer a Lisp-1 versus Lisp-2 issue, since the X being called
 KK> is in the second position.

i think that point here is to have a shorthand notation.

(funcall X zzz) won't be anyhow better than (gethash X zzz), while
(X zzz), arguably, is.

so it is not a solution to the original problem.

 KK> There is no reason why the behavior can't be extended to allow other
 KK> kinds of objects to serve as functions.

sure, you can do that in straightforward way via funcallable instances.
but that does not solve original problem.

 KK> You could also allow an extension that would allow funcallable objects
 KK> other than functions to be installed under function bindings.
 KK> E.g.
 KK>    (letf ((a #(1 2 3))) ;; not to be confused with flet

it is not a problem to do this with custom binding constructs, and
there was couple of examples for such binding constructs three days
ago, when question was posted, and mine was among them, btw.

but the idea was to have this feature transparently, i guess. 
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4947ee2f$0$90275$14726298@news.sunsite.dk>
 ??>> by being "Lisp-1", duh. when there is single namespace, you do not
 ??>> need any runtime logic to check if thingie is a function or a
 ??>> hashtable.

 j> So, how do you get Clojure to accept strings in function position?
 j> ("abc" 1)

 j> and

 j> (let ((s "abc"))     ; whatever the LET syntax is for Clojure
 j>   (s 1))

 j> (let ((s "abc") (i 1))     ; whatever the LET syntax is for Clojure
 j>   (s i))

 j> Without runtime checks, please.

the need for runtime checks here has absolutely nothing to do with hashtable 
funcallability.
consider such example:

(let ((s "abc")) (s))

if strings are not funcallable, how would language runtime know that it 
needs to signal error here?
obviously it needs to check contents of variable. variable could be unbound, 
in this case it has to signal different error.
or it can be nil. apparently, check is REQUIRED here.

it is another thing, this check can be made minimal, this can be just a 
single lookup and check -- overhead would be
negligable comparing to CALL expenses.

if you're deeply concerned about this overhead, you can avoid this making 
everything funcallable.
then you call string object, but it will signal an error. in this case you 
need special objects to
represent NIL and unbound variables, they also need special action to be 
invoked when called.

alternatively you can trap faulty calls and deduce error condition from 
stack.
(as far as i understand, that's what SBCL does. it also needs to check 
funcallability of symbols
as they can me fmakunbounded at any time.)

as for Clojure, here is how calling variables is implemented:

public final class Var implements IFn, IRef, IObj{


final public IFn fn(){
 return (IFn) get();
}

public Object invoke() throws Exception{
 return fn().invoke();
}

each time you invoke it, it does Java cast, that does appropriate checks and 
signals error.
but cast overhead is last thing you should worry about, get() call here is 
much more expensive,
as it does thread-local lookup in quite complex way.

 j> So, Alex, a Lisp-1 does not magically get away with
 j> runtime checks. The hashtable feature is built
 j> into the Clojure implementation and is independent
 j> of Clojure being a Lisp-1.


my point is that it is not possible to make it in Lisp-n -- with runtime 
checks
or whatever, it just violates Lisp-n semantics. with such feature variables
will shadow functions, and so it won't be Lisp-n anymore.

Leslie's version uses BOUNDP, and so it works only for special variables and 
not for lexical ones.
this is _very_ limited solution, as most variables are lexical ones.
From: Kaz Kylheku
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <20090101171504.588@gmail.com>
On 2008-12-16, Alex Mizrahi <········@users.sourceforge.net> wrote:
> (let ((s "abc")) (s))
>
> if strings are not funcallable, how would language runtime know that it 
> needs to signal error here?

In this particular case, it can be diagnosed at compile time. Data flow
analysis tells us that at the expression (s), the value "abcd" emanating from
the let is still live there, since no intervening assignment to S is possible
(in fact there isn't one anywhere at all in the scope where S is visible). So
statically we can know that "abcd" is being called as a function and diagnose
it.
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4948cab2$0$90273$14726298@news.sunsite.dk>
 ??>> (let ((s "abc")) (s))
 ??>>
 ??>> if strings are not funcallable, how would language runtime know that
 ??>> it needs to signal error here?

 KK> In this particular case, it can be diagnosed at compile time. Data flow
 KK> analysis tells us that at the expression (s), the value "abcd"
 KK> emanating from the let is still live there, since no intervening
 KK> assignment to S is possible (in fact there isn't one anywhere at all in
 KK> the scope where S is visible). So statically we can know that "abcd" is
 KK> being called as a function and diagnose it.

yep. but it is easy to fix:

(defun fff (s) (s))

(fff (lambda () "123"))

(fff "123")

analysis won't help in general case 
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <4945593e$0$90268$14726298@news.sunsite.dk>
 ??>> It's not that easy. The problem is, that there is no way to override
 ??>> the syntax of a cl funtion call. You can either have a symbol denoting
 ??>> a function or a lambda expression.

 LPP> Why not?

because it is not Scheme. 
From: Joshua Taylor
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <76eaac4c-597b-45a8-b60b-279e36b94bd3@s9g2000vbp.googlegroups.com>
On Dec 14, 6:01 am, "Leslie P. Polzer" <·············@gmx.net> wrote:
> Clojure, from what I've gathered, lets one access hash tables just by
> referring to them in the CAR of an evaluated form:
>
> (defparameter ht (make-hash-table))
>
> (ht 'foo) == (gethash 'foo ht)
> (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> It should be easy to emulate the hash table reader at least in
> function context, by defining a custom DEFUN-wrapping macro that
> dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> Is this also possible for the SETF expansion? I think it should be,
> but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
>   Leslie

I don't know if it would be considered "easy", but you might be
interested at a blog post by Geoff Wozniak on Exploring Lisp. It's
about funcallable objects in general.

http://exploring-lisp.blogspot.com/2007/05/objects-as-functions.html

This doesn't provide an entire solution, since you'd still need to
write a hash table implementation. In your own package, though, you
could shadow the CL hash table functions and provide the same
interface though your own symbols (make-hash-table, gethash, …).

There are still some issue with the idea though, since CL is a Lisp-2,
you end up having to do things such as those in Geoff's post, such as:

(defun f () nil)
(setf (symbol-function 'f)
      (make-instance 'setl-map :pairs '((1 . 100) (2 . 200))))

so that (f …) will be a call to the correct object, but you still
can't do things like:

(let ((f (make-funcallable-hash-table …)))
  (f …))

and be calling the local funcallable object. Instead you'd have to:

(let ((f (make-funcallable-hash-table …)))
  (funcall f …))

but (funcall f …) isn't really any more concise than (gethash f …), so
we're right back where we started.

//JT
From: Vsevolod
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <dce58868-f06e-472b-ae3f-3d4d5d449438@y1g2000pra.googlegroups.com>
On Dec 14, 1:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
> Clojure, from what I've gathered, lets one access hash tables just by
> referring to them in the CAR of an evaluated form:
>
> (defparameter ht (make-hash-table))
>
> (ht 'foo) == (gethash 'foo ht)
> (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> It should be easy to emulate the hash table reader at least in
> function context, by defining a custom DEFUN-wrapping macro that
> dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> Is this also possible for the SETF expansion? I think it should be,
> but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
>   Leslie

You can achieve it with a sort of such simple macro as the following
(a naive implementation without handling of parameters of make-hash-
table):
(defmacro def-hash-table (name)
  `(progn (defparameter ,name (make-hash-table))
               (defun ,name (key &optional default)
                  (gethash key ,name default))))
which uses Lisp's separation of namespaces.

PS. But, in my opinion, Lisp-n is better, because you virtually always
know, what you are dealing with -- a var or a function.
From: Rainer Joswig
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <joswig-E56D2D.12152614122008@news-europe.giganews.com>
In article 
<····································@r37g2000prr.googlegroups.com>,
 "Leslie P. Polzer" <·············@gmx.net> wrote:

> Clojure, from what I've gathered, lets one access hash tables just by
> referring to them in the CAR of an evaluated form:
> 
> (defparameter ht (make-hash-table))
> 
> (ht 'foo) == (gethash 'foo ht)
> (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)

Compare that with Lisp Machine Lisp from 70s/80s:

Command: ("abc" 1)
#\b

That's an old Lisp feature to make some data objects
having a functional interpretation. In LML for examples
arrays in functional position were evaluated as doing
AREF.

> 
> It should be easy to emulate the hash table reader at least in
> function context, by defining a custom DEFUN-wrapping macro that
> dispatches either to FUNCALL or to GETHASH depending on the data type.

I don't think it is that easy...

> 
> Is this also possible for the SETF expansion? I think it should be,
> but I hardly ever use the DEFSETF facilities so I'm not sure how.
> 
>   Leslie

-- 
http://lispm.dyndns.org/
From: Alex Mizrahi
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <49451900$0$90264$14726298@news.sunsite.dk>
 LPP> Clojure, from what I've gathered, lets one access hash tables just by
 LPP> referring to them in the CAR of an evaluated form:

 LPP> (defparameter ht (make-hash-table))

 LPP> (ht 'foo) == (gethash 'foo ht)
 LPP> (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)

 LPP> It should be easy to emulate the hash table reader at least in
 LPP> function context, by defining a custom DEFUN-wrapping macro that
 LPP> dispatches either to FUNCALL or to GETHASH depending on the data type.

 LPP> Is this also possible for the SETF expansion? I think it should be,
 LPP> but I hardly ever use the DEFSETF facilities so I'm not sure how.

it is fairly easy to do this for custom binding contstructs. something like 
this:

(defmacro defhash (name value)
 `(progn (defparameter ,name ,value)
            (defun ,name (key) (gethash key ,name))
            (defun (setf ,name) (value key) (setf (gethash key ,name) 
value))))

(defmacro lethash ((name value) &body body)
 `(let ((,name ,value))
   (macrolet ((,name (key) `(gethash ,key ,,name)))
    ,@body)))

if you want to use normal lisp binding constructs, that becomes more tricky.
you can do this for special variables one way or another. but for lexical 
bindings
that becomes really hard -- basically you need to modify all binding 
constructs
and inject macros via macrolet that will deal with the case where variable 
name
is used like a function. handling setf wil be even more problematic..
but there is actually have little sense -- essentially that will be not a 
Common Lisp
but some new Lisp-1 dialect [*]. perhaps then just port Clojure (or Arc or 
whatever) to
 Common Lisp..

*: consider such case:

 (defun foo (x)
   (let ((foo (make-hash-table)))
       (foo x)))

does (foo x) mean a function call or ht lookup? the only way to solve 
ambiguity is
to have single namespace. 
From: ···········@mac.com
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <01c6aac3-16cf-4a6e-a7dc-bfdaf0c29cec@h5g2000yqh.googlegroups.com>
On Dec 14, 9:32 am, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>
> *: consider such case:
>
>  (defun foo (x)
>    (let ((foo (make-hash-table)))
>        (foo x)))
>
> does (foo x) mean a function call or ht lookup? the only way to solve
> ambiguity is
> to have single namespace.

Yes, and what about this...

(setq car (make-hash-table))

Treating as a symbol is fine
  (setf (gethash 'a car) 'quux)

(gethash 'a car) => quux

But what happens with

(car '(foo or quux)) ?

It clashes with the CL:CAR function. Is the compiler supposed to
understand that the value of the symbol is a hashtable hence
effectively producing (gethash ...)? Is the value of CAR (value is
changeable) now the hash table? Yes, probably. And what is the value
of the function slot? (car '(a b c)) => a or does it now have
#'gethash. But what happens if it finds (funcall car 'a).

IMHO, I think this 'extension' is cute, useful in certain
circumstances, and not well thought-out. Better to make a macro as
noted above. If the generated function (embedded gethash) closes over
the hash table, then it's not dependent on the value of the symbol.
But allowing DEFPARAMETER or even SETQ strikes me as confusing and not
worth the time.
From: Vsevolod
Subject: Re: Clojure hash table accessors in CL
Date: 
Message-ID: <1e73981f-8b00-4ba4-a89e-0c21a8e33498@k24g2000pri.googlegroups.com>
On Dec 14, 1:01 pm, "Leslie P. Polzer" <·············@gmx.net> wrote:
> Clojure, from what I've gathered, lets one access hash tables just by
> referring to them in the CAR of an evaluated form:
>
> (defparameter ht (make-hash-table))
>
> (ht 'foo) == (gethash 'foo ht)
> (setf (ht 'foo) t) == (setf (gethash 'foo ht) t)
>
> It should be easy to emulate the hash table reader at least in
> function context, by defining a custom DEFUN-wrapping macro that
> dispatches either to FUNCALL or to GETHASH depending on the data type.
>
> Is this also possible for the SETF expansion? I think it should be,
> but I hardly ever use the DEFSETF facilities so I'm not sure how.
>
>   Leslie

...and since you want an unCommon Lisp syntax, you can also use reader
macros, for example this, which can be made quite extensible:
(defun |[-reader| (stream char)
  (declare (ignore char))
  (let* ((lst (read-delimited-list #\] stream t))
         (name (car lst))
         (2nd (cadr lst)))
    `(cond
       ((typep ,name 'hash-table) (gethash ,2nd ,name))
       ((keywordp ,name) (gethash ,name ,2nd))
       ((typep ,name 'sequence) (elt ,name ,2nd)))))

(set-macro-character #\[ #'|[-reader|)
(set-macro-character #\] (get-macro-character #\) nil))

CL-USER> (defvar ht (make-hash-table))
HT
CL-USER> (setf (gethash :a ht) 1)
1
CL-USER> [:a ht]
1
T
CL-USER> [ht :a]
1
T

But in this extensible case you'll have problems with setf. If you go
just for hash-tables, the dispatch can be done at read-time:

(defun |[-reader| (stream char)
  (declare (ignore char))
  (let* ((lst (read-delimited-list #\] stream t))
         (name (car lst))
         (2nd (cadr lst)))
    (if (keywordp name) `(gethash ,name ,2nd)
        `(gethash ,2nd ,name))))

CL-USER> (setf [:a ht] 2)
2

Cheers,
Vsevolod