Re: Sort order not always kept when querying the database

2019-10-15 Thread cilz

Hello Alex,

Thanks for this message.

Le 09/10/2019 à 21:08, Alexander Burger a écrit :

Hi Eric,

thanks for sharing your code!

As far I could see on a first scan, it looks very good.



The result starts with "Wednesday" instead of
"Monday" as for the week 41 or other weeks!

The values have no inherent ordering, as they all have the same key (the
combination of year and day). So they may appear in any order, just by chance
starting on Monday (probably due to the order the objects were imported).

OK.

If you want to collect the days in order, you could just use the 'date' index,
and calculate the range from the week (I don't know that algorithm at the
moment. Assuming we had such functions, we could do

(collect 'date '+Agenda (weekStart 2019 42) (weekEnd 2019 42))

This would be the most efficient way.

Hum...

Otherwise you could sort it

   (by '((This) (: date)) sort (collect 'year '+Agenda (2019 42)))

with a little more overhead.


Yes this works very well. Now, I have all my weeks sorted from monday to 
sunday.


My new functions to achieve this:

# print any database outputs as a table.
(de showData (DBOutputs)
   (let Fmt *Params
  (tab Fmt "id" "date" "mag" "year" "mthnum" "mthtxt" "week" 
"daynum" "daytxt" "status")
  (tab Fmt "" "--" "--" "" "--" "--" 
"" "--" "--" "--")

  (for This DBOutputs
 (tab Fmt (: id) (: date) (: mag) (: year) (: monthnum)
  (: monthtxt) (: week) (: daynum) (: daytxt) (: 
status) ) ) ) )


# show a given week sorted by date.
# usage: (showThisWeek 2019 42)
(de showThisWeek (Year Week)
   (showData (by '((This) (: date)) sort (collect 'year '+Agenda (list 
Year Week )


Best,

Eric


--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Sort order not always kept when querying the database

2019-10-09 Thread Alexander Burger
Hi Eric,

thanks for sharing your code!

As far I could see on a first scan, it looks very good.


> The result starts with "Wednesday" instead of
> "Monday" as for the week 41 or other weeks!

The values have no inherent ordering, as they all have the same key (the
combination of year and day). So they may appear in any order, just by chance
starting on Monday (probably due to the order the objects were imported).

If you want to collect the days in order, you could just use the 'date' index,
and calculate the range from the week (I don't know that algorithm at the
moment. Assuming we had such functions, we could do

   (collect 'date '+Agenda (weekStart 2019 42) (weekEnd 2019 42))

This would be the most efficient way.


Otherwise you could sort it

  (by '((This) (: date)) sort (collect 'year '+Agenda (2019 42)))

with a little more overhead.

☺/ A!ex


-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Sort order not always kept when querying the database

2019-10-09 Thread cilz

Gear Guys,

This mail is a kind of follow-up to the thread started here: 
https://www.mail-archive.com/picolisp@software-lab.de/msg09124.html .


Based on Alex's tips I have set up my database like this:

(class +Agenda +Entity)
(rel id    (+Key +Number))
(rel date  (+Ref +Date))
(rel mag   (+Idx +String))
(rel year  (+Aux +Ref +Number) (week))
(rel monthnum  (+Ref +Number))
(rel monthtxt  (+Idx +String))
(rel week  (+Ref +Number))
(rel daynum    (+Ref +Number))
(rel daytxt    (+Idx +String))
(rel status    (+Idx +String))

I read the data from a text file which is in reverse order and looks 
like this for the current month:


# = Agenda =
"date" "mag" "status"
# = 2019 =
# - october

2019-10-31 XYZ ?
2019-10-30 XYZ ?
2019-10-29 XYZ ?
2019-10-28 XYZ ?
2019-10-27 XYZ Rh
2019-10-26 XYZ Rh
2019-10-25 XYZ Cp
2019-10-24 XYZ Cp
2019-10-23 XYZ Cp
2019-10-22 XYZ Cp
2019-10-21 XYZ Cp
2019-10-20 XYZ Rh
2019-10-19 XYZ J
2019-10-18 XYZ J
2019-10-17 XYZ O
2019-10-16 XYZ F
2019-10-15 XYZ Rh
2019-10-14 XYZ F
2019-10-13 XYZ F
2019-10-12 XYZ Rh
2019-10-11 XYZ Liv
2019-10-10 XYZ O
2019-10-09 XYZ Rh
2019-10-08 XYZ O
2019-10-07 XYZ F
2019-10-06 XYZ Rh
2019-10-05 XYZ J
2019-10-04 XYZ J
2019-10-03 XYZ Rdm
2019-10-02 XYZ J
2019-10-01 XYZ F

I read and feed the database with the following function:

(de feedAgendaDB (X)
   (in (list "grep" "-v" "#" X)
  (line) # skip the first line.
 (until (eof)
    # file schema: "date" "mag" "status"
    (let (Dat (read) Mag (read) Stat (read))
   (new! '(+Agenda)
  # DB schema: "id" "date" "mag" "year" "monthnum" 
"monthtxt" "week" "daynum" "daytxt" "status"

  'id   (format (pack (split (chop Dat) "-")))
  'date ($dat Dat "-")
  'mag  Mag
  'year (format (car (mapcar pack (split (chop Dat) 
"-"
  'monthnum (format (cadr (mapcar pack (split (chop 
Dat) "-"
  'monthtxt (get *MonFmt (format (cadr (mapcar pack 
(split (chop Dat) "-")

  'week (week ($dat Dat "-"))
  'daynum   (format (pack (get (split (chop Dat) "-") 3)))
  'daytxt   (day ($dat Dat "-"))
  'status   Stat ) ) ) ) )

where X is the file path.

In order to display the results of data queries I use these functions:

(setq *Params (-10 -9 -8 -7 -11 -11 -7 -8 -11 -8))

(de agendaShowOne (This)
   (let Fmt *Params
  (with This
 (tab Fmt (: id) (: date) (: mag) (: year) (: monthnum)
  (: monthtxt) (: week) (: daynum) (: daytxt) (: 
status) ) ) ) )


(de agendaShowAll (X)
   (mapcar agendaShowOne X) )

So far my main use of the data is to query the database to see what 
happen during one week and I do it this way:


(agendaShowAll (reverse (collect 'year '+Agenda (2019 41

with this result for the week 41:

20191007  737645   mag150  2019   10 October    41 7   
Monday F
20191008  737646   mag150  2019   10 October    41 8   
Tuesday    O
20191009  737647   mag150  2019   10 October    41 9   
Wednesday  Rh
20191010  737648   mag150  2019   10 October    41 10  
Thursday   O
20191011  737649   mag150  2019   10 October    41 11  
Friday Liv
20191012  737650   mag150  2019   10 October    41 12  
Saturday   Rh
20191013  737651   mag150  2019   10 October    41 13  
Sunday F


**My question is about the week 42 for which the result of the query is:**

(agendaShowAll (reverse (collect 'year '+Agenda (2019 42

20191016  737654   mag150  2019   10 October    42 16  
Wednesday  F
20191017  737655   mag150  2019   10 October    42 17  
Thursday   O
20191018  737656   mag150  2019   10 October    42 18  
Friday J
20191019  737657   mag150  2019   10 October    42 19  
Saturday   J
20191020  737658   mag150  2019   10 October    42 20  
Sunday Rh
20191014  737652   mag150  2019   10 October    42 14  
Monday F
20191015  737653   mag150  2019   10 October    42 15  
Tuesday    Rh


The result starts with "Wednesday" instead of "Monday" as for the week 
41 or other weeks! Is there any reason explaining this strange 
behaviour? What am I doing wrong?


For what is worth I'm using PIL:

(version)
18.9.5

on Manjaro linux.

Thanks, best,

Eric



--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Behavior of sort

2019-05-05 Thread JmageK
Copy appears to be most reliable as it does not modify the original list. Maybe 
a tiny bit slower than ->(setq L (sort L))

: (setq L (3 2 1 4 9 0]
-> (3 2 1 4 9 0)

: (sort (copy L]
-> (0 1 2 3 4 9)
: L
-> (3 2 1 4 9 0) 

: (setq L (sort L]
-> (0 1 2 3 4 9)
: L-> (0 1 2 3 4 9)

JmageK
-- 
Securely sent with Tutanota



May 4, 2019, 8:10 PM by a...@software-lab.de:

> Hi  Kashyap,
>
>> I noticed an odd behavior of sort -
>> (setq L '((2) (1) ))
>> (sort L)
>>
>
> Note that 'sort' is a destructive function, it modifies the order of cells
> in-place. Thus you must use the return value of 'sort', it may return another
> cell than was passed to it.
>
> In the above, the return value of 'sort' is ignored and thus lost.
>
> Try either
>
> : (length (sory L))
>
> or
>
> : (setq L (sort L))
>
> ☺/ A!ex
>
> -- 
> UNSUBSCRIBE: mailto:> picolisp@software-lab.de 
> <mailto:picolisp@software-lab.de>> ?subject=Unsubscribe
>


--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Behavior of sort

2019-05-04 Thread Lindsay Lawrence
Hi,

The sort is destructive of the input.
https://software-lab.de/doc/refS.html#sort
There are other functions that behave like this that you need to be aware
of when writing code.
You have to assign the result of the sort to another variable. Back to
itself is fine.

: (setq L '((3) (2) (1)))
-> ((3) (2) (1))
: (show L)
-> ((3) (2) (1))
: (setq L (sort L))
-> ((1) (2) (3))
: (show L)
-> ((1) (2) (3))
: (length L)
-> 3

Regards,
/Lindsay


On Sat, May 4, 2019 at 7:32 AM C K Kashyap  wrote:

> Hi all,
>
> I noticed an odd behavior of sort -
>
> (setq L '((2) (1) ))
>
>
> (println (length L)) # 2 as expected
>
> (sort L)
>
> (println (length L)) # why 1?
>
> (println L) # ((2))
>
> (bye)
>
> I would expect sort not to change the length. Am I missing something here
> or is sort broken?
> Regards,
> Kashyap
>


Re: Behavior of sort

2019-05-04 Thread Alexander Burger
Hi  Kashyap,

> I noticed an odd behavior of sort -
> (setq L '((2) (1) ))
> (sort L)

Note that 'sort' is a destructive function, it modifies the order of cells
in-place. Thus you must use the return value of 'sort', it may return another
cell than was passed to it.

In the above, the return value of 'sort' is ignored and thus lost.

Try either

: (length (sory L))

or

: (setq L (sort L))

☺/ A!ex

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Behavior of sort

2019-05-04 Thread C K Kashyap
Hi all,

I noticed an odd behavior of sort -

(setq L '((2) (1) ))


(println (length L)) # 2 as expected

(sort L)

(println (length L)) # why 1?

(println L) # ((2))

(bye)

I would expect sort not to change the length. Am I missing something here
or is sort broken?
Regards,
Kashyap


Re: Unexpected behaviour from (sort) with

2016-10-01 Thread Alexander Burger
Hi Rowan,

> first sentence at http://www.software-lab.de/doc/refS.html#sort
> changed from:
> 
> > Sorts lst by destructively exchanging its elements.
> 
> to something more explicit like:
> 
> > Returns a sorted lst by destructively exchanging the original lst's 
> > elements.

Good idea! Thanks!

Done :)


> guess there may be other "destructive but not in-place" functions
> whose documentation this suggestion could be relevant to as well. Of

Yes. 'flip' is such a typical case:

   : (setq L (1 2 3 4))
   -> (1 2 3 4)
   : (flip L)
   -> (4 3 2 1)
   : L
   -> (1)  # Oops

However, the ref of 'flip' is already as you suggest.

♪♫ Alex
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Unexpected behaviour from (sort) with

2016-10-01 Thread Rowan Thorpe
On 30 September 2016 at 20:24, Alexander Burger <a...@software-lab.de> wrote:
> Hi Rowan,
>
> the explanation is simple.
> ...
> It is the *return* value of 'sort' which is relevant:
> ...

Ah, [facepalm], thanks. Because I hadn't used picolisp for a while,
when I first used (sort) again in a new context I saw the altered (but
not NIL) initial ("A") value before paying attention to the
return-value, and was so convinced that it must be the meaningful part
- and that (sort) must be "destructive and in-place" - that I never
even looked at sort's return-value (or noticed that the documentation
shows its return-values). Ironically picolisp code of mine from 2
years ago uses it correctly [sigh]. I suggest it might be more useful
for newcomers, for people-with-terrible-memory, and for
people-who-have-to-do-too-much-context-switching (like me) if the
first sentence at http://www.software-lab.de/doc/refS.html#sort
changed from:

> Sorts lst by destructively exchanging its elements.

to something more explicit like:

> Returns a sorted lst by destructively exchanging the original lst's elements.

I realise the examples implicitly show the "returns..." part of this,
but it is easy to get distracted from that by the initial "lst" being
transformed (but not NIL-ed) in such initially surprising ways. I
guess there may be other "destructive but not in-place" functions
whose documentation this suggestion could be relevant to as well. Of
course you might feel that is being too verbose in order to pander to
the n00bs and the forgetful though...

-- 
Rowan Thorpe
PGP fingerprint:
 BB0A 0787 C0EE BDD8 7F97  3D30 49F2 13A5 265D CCBD

"A riot is the language of the unheard." - Dr. Martin Luther King
"There is a great difference between worry and concern. A
worried person sees a problem, and a concerned person solves a
problem." - Harold Stephens
"Ignorance requires no apologies when it presents questions
rather than assertions." - Michael Sierchio (OpenSSL mailing list)
"What we need more than an end to wars is an end to the
beginning of all wars." - Franklin Roosevelt
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Unexpected behaviour from (sort) with

2016-09-30 Thread Alexander Burger
Hi Rowan,

the explanation is simple.

> (println A) (sort A) (println A)

This is not the right way. Though 'sort' works destructively, this does
not mean that it sorts the cells in-place. It is the *return* value of
'sort' which is relevant:

   (println A)
   (println (sort A))

or

   (println A)
   (setq A (sort A))
   (println A)

♪♫ Alex
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Unexpected behaviour from (sort) with transient-sym-with-leading-numeral-in-cdr

2016-09-30 Thread Rowan Thorpe
I have a perplexing situation with the (sort) function sorting
alphanumeric elements, and can't find any explanation in the
documentation after searching for a while. Unless I am
misunderstanding some painfully fundamental point, this appears to be
a bug.

When I try to sort alphanumeric transient-syms it seems that the
(sort) function bails out early as soon as it hits an element from the
CDR with leading numeral (I guess it is internally attempting to
transform each transient-sym to an internal-sym as it iterates through
the CDR, which won't work for e.g. "3a"), and then it seems to quietly
return one of the halved partitions being internally constructed by
the mergesort algorithm rather than erroring out loudly. I would
expect that:

 * sorting alphanumerically would be possible (leading numbers before
letters), as e.g. (< "3a" "a") and (< "a" "3a") in isolation both work
as expected
 * if it is going to fail it should make it clear that it is failing
rather than "successfully" presenting an incorrect (and initially
baffling) result

The same happens whether assigning A inside (let) or assigning A
beforehand with (set). I am using 64bit (assembler) picolisp v16.7.17
(Debian package). Please let me know if you need more information (or
if I'm an idiot and just didn't understand something). Example
fail-scenarios are below:

> # -- "sort"
> : (let (A '("t" "z" "q" "a" "3a" "x3" "3")) (println A) (sort A) (println A))
> ("t" "z" "q" "a" "3a" "x3" "3")
> ("t" "x3" "z")
> -> ("t" "x3" "z")

> # -- "sort <" [same as above, with implicit < sort-function]
> : (let (A '("t" "z" "q" "a" "3a" "x3" "3")) (println A) (sort A <) (println 
> A))
> ("t" "z" "q" "a" "3a" "x3" "3")
> ("t" "x3" "z")
> -> ("t" "x3" "z")

> # -- "sort >"
> : (let (A '("t" "z" "q" "a" "3a" "x3" "3")) (println A) (sort A >) (println 
> A))
> ("t" "z" "q" "a" "3a" "x3" "3")
> ("t" "q" "a" "3a" "3")
> -> ("t" "q" "a" "3a" "3")

> # -- "sort with CAR-with-leading-numeral"
> : (let (A '("4b" "t" "z" "q" "a" "3a" "x3" "3")) (println A) (sort A) 
> (println A))
> ("4b" "t" "z" "q" "a" "3a" "x3" "3")
> ("4b" "a" "q" "t" "x3" "z")
> -> ("4b" "a" "q" "t" "x3" "z")

> # -- "sort > with CAR-with-leading-numeral"
> : (let (A '("4b" "t" "z" "q" "a" "3a" "x3" "3")) (println A) (sort A >) 
> (println A))
> ("4b" "t" "z" "q" "a" "3a" "x3" "3")
> ("4b" "3a" "3")
> -> ("4b" "3a" "3")

> # -- "sort quoted list" [doesn't do anything at all]
> : (let (A '("t" "z" "q" "a" "3a" "x3" "3")) (println A) (sort 'A) (println A))
> ("t" "z" "q" "a" "3a" "x3" "3")
> ("t" "z" "q" "a" "3a" "x3" "3")
> -> ("t" "z" "q" "a" "3a" "x3" "3")

-- 
Rowan Thorpe
PGP fingerprint:
 BB0A 0787 C0EE BDD8 7F97  3D30 49F2 13A5 265D CCBD

"A riot is the language of the unheard." - Dr. Martin Luther King
"There is a great difference between worry and concern. A
worried person sees a problem, and a concerned person solves a
problem." - Harold Stephens
"Ignorance requires no apologies when it presents questions
rather than assertions." - Michael Sierchio (OpenSSL mailing list)
"What we need more than an end to wars is an end to the
beginning of all wars." - Franklin Roosevelt
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: Strange sort behaviour

2010-08-20 Thread Alexander Burger
Hi Jon,

 I can accept your explanation, but then I think the docs should make it
 clear that the sorted list is what's returned by the function, and that
 the state of the input list afterwards can be somewhat unpredictable.

I agree that the documentation is rather terse, but that's a feature ;-)

In general it should be understood that destructive functions (may)
modify their argument values in individual ways.

Take 'flip', the destructive version of 'reverse'

   : (setq L (1 2 3 4 5 6))
   - (1 2 3 4 5 6)
   : (flip L)  
   - (6 5 4 3 2 1)
   : L   
   - (1)

or 'conc', archetype of all destructive functions. While it sometimes
works as one might expect

   : (setq A (1 2 3)  B (4 5 6))
   - (4 5 6)
   : (conc A B) 
   - (1 2 3 4 5 6)
   : A 
   - (1 2 3 4 5 6)
   : B
   - (4 5 6)

'A' is modified the way you expected for 'sort' (i.e. holding the return
value). This is not the case, however, if the first argument is 'NIL'

   : (setq A NIL  B (4 5 6))
   - (4 5 6)
   : (conc A B) 
   - (4 5 6)
   : A 
   - NIL
   : B
   - (4 5 6)

Then there is nothing to concat to, and only the return value is
meaningful.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Strange sort behaviour

2010-08-19 Thread Jon Kleiser

Hi,

The docs on the 'sort' function says Sorts lst by destructively 
exchanging its elements. From this I get the impression that


(let L (3 2 5 4) (sort L) L)

should give the same result as

(let L (3 2 5 4) (sort L))

but that's not so, as the first one reveals that L get the value
(3 4 5), while the (more expected) value returned by the (sort L) itself 
was (2 3 4 5). Why couldn't L simply be given the same value?


/Jon
--
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: Strange sort behaviour

2010-08-19 Thread Tomas Hlavaty
Hi Jon,

 (let L (3 2 5 4) (sort L) L)

 should give the same result as

 (let L (3 2 5 4) (sort L))

it should not;-)

 Why couldn't L simply be given the same value?

L is given the same value which you print in the first case.  In the
second case, you printed out the return value of 'sort'.

L still points to the same cons cell, but 'sort' modified the list
underneath.  You'd have to do (setq L (sort L)) to get the sorted list
into the variable L.

: (let L (3 2 5 4) (setq L (sort L)) L)
- (2 3 4 5)

 The docs on the 'sort' function says Sorts lst by destructively
 exchanging its elements.

That's correct.  In your examples, L points to the first cons cell of
the list initially.  However, 'sort' rearranges the list destructively
and that cons cell (pointed by L) is no longer the first one.

Hope it helps,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-07 Thread Tomas Hlavaty
Hi Alex,

:  (let L (make (do 10 (link (rand (bench (sort L) T))
0.251 sec
- T

thanks for pointing out the 'bench' function;-)

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-07 Thread Tomas Hlavaty
Hi Alex,

 A typical example would be sorting a list of customers by city, name and
 customer number, in that order. A binary comparison for 'sort2' would
 look like

(sort2
   (collect ... '+CuSu ...)
   '((CuSu1 CuSu2)
  (cond
 (( (; CuSu1 ort) (; CuSu2 ort))
( (; CuSu2 ort) (; CuSu1 ort)) )
 (( (; CuSu1 nm) (; CuSu2 nm))
( (; CuSu2 nm) (; CuSu1 nm)) )
 (T
( (; CuSu2 nr) (; CuSu1 nr)) ) ) ) )

 This binary function is rather complicated (and thus slow), and it might
 be called nearly O(N^2) times.

it will be called as many times as the C function 'compare' is called.
Not sure about the picolisp 'sort' function, but usual sorting
algorithms are O(N*log(N)) so it will be called O(N^2) times only if
the built-in 'sort' is O(N^2).  I guess the built-in 'sort' function
is O(N*log(N)) so the code above will be O(N*log(N)) too.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-07 Thread Tomas Hlavaty
 I'm not sure. I feel that it is its ugliness which predestines it to
 denote such a local concept.

Fair enough:-)

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-07 Thread Tomas Hlavaty
Hi Alex,

 and on top of that calls the retrieval code twice on each
 invocation).

I am not sure about what you mean.  The 'sort' algorithm have some
strategy how it accesses the elements and by the time the function
compare() is called, it already has the elements available so it does
not have to retrieve them.

Thanks,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-07 Thread Alexander Burger
Hi Tomas,

 strategy how it accesses the elements and by the time the function
 compare() is called, it already has the elements available so it does
 not have to retrieve them.

With retrieve I meant the raw data which are finally compared.

For example, look at the compare() method in AlphanumComparator.java
from your link http://www.davekoelle.com/alphanum.html;.

Each time two objects are compared, there are string length()s
calculated, getChunk()s performed, the lengths of those chunks
calculated, and so on. This is done for both objects at each comparison.
And each time a given object is compared to another object, the
algorithm is performed again.

The code is also twice as long, needing s1.length() and s2.length(),
thisChunk = getChunk() and thatChunk = getChunk(). So I would expect a
unary function shorter and more to the point in general.

With the 'by' mechanism of PicoLisp, this retrieval of raw data is
performed only once for each object. The 'sort' routine then just has to
do the direct comparison of simple lisp structures.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-06 Thread Alexander Burger
Hi Tomas,

 As the list being sorted is finite, it must be possible to come up
 with a unary weighting function.  The question is whether the unary
 function is always better then the binary predicate?

I do believe so. The unary function is simpler (as you see from the
previous examples), and faster (because the retrieval code, which
usually takes more time than the actual comparison, is called O(N)
times, as opposed to the binary predicate which is called more often,
and on top of that calls the retrieval code twice on each invocation).


 I updated http://logand.com/picoWiki/multimethods which I didn't
 manage to do last time as the internet in the internet cafe went
 down:-(

;-)


 (de subclass? (X Y)
(if (pair Y)
   (loop
  (NIL Y T)
  (NIL (subclass? X (pop 'Y))) )
   (let Q (if (pair X) X (val X)) # dfs
  (use H
 (loop
(NIL Q)
(setq H (pop 'Q))
(T (= H Y) T)
(for HH (val H)
   (push 'Q HH) ) ) ) ) ) )

BTW, this is almost the same as what 'isa' does. So it looks like that
instead of

   (subclass? LH RH)

you could simply write

   (isa RH LH)


 (de mmLt (L R)
(use (LH RH)
   (loop
  (NIL (or L R))
  (setq LH (pop 'L) RH (pop 'R))
  (T (and (not LH) RH) NIL)
  (T
   (when LH
  (or (not RH) (and ( LH RH) (subclass? LH RH))) )
   T ) ) ) )
 ...
 I admit I cannot see a way of defining a unary weighting function
 easily.  Maybe this is the challenge, switching from binary to unary
 function, in this case?

I don't completely understand the exact ordering requirements, but I
feel that something like the following should work:

If you have a function 'rankClass' which returns the depth where a class
in the hierarchy is located

   (de rankClass (Cls)
  (cond
 ((not Cls) 0)
 ((atom Cls) (rankClass (type Cls)))
 (T
(dec
   (min
  (rankClass (car Cls))
  (rankClass (cdr Cls)) ) ) ) ) )

then you could sort a list of the form

   (setq Table
  (quote
 (((+Cls1 +Cls2) (+Cls3 +Cls4)) ..)
 (((+Cls5 +Cls6) (+Cls7 +Cls8)) ..)
 ... ) )

with a function returning a list of lists of weights

   (by
  '((Lst)
 (mapcar '((L) (mapcar rankClass L)) (car Lst)) )
  sort
  Table )


 I would be curious to compare the running times for the multimethod
 example, if there is a reasonably simple unary function, it should
 be significantly faster provided there are many multimethods;-) (Even
 though the speed does not matter in this case, as sorting takes place
 during load time/method definition, not application.)

That's right, but interesting anyway ;-)

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-06 Thread Alexander Burger
Hi Tomas,

thinking about it, I probably wrote nonsense yesterday:

 If you have a function 'rankClass' which returns the depth where a class
 in the hierarchy is located
 
(de rankClass (Cls)
 ...

The depth does not matter, right?

Instead, the top-level base classes must be compared (you used
'subclass?' respectively 'isa' after all). And, it looks like 'NIL's
must be greater than anything else.


So a function that converts a list like

   ((Cls1) (Cls2))

to

   (Top1 Top2)

and

   ((Cls1) NIL)

to

   (Top1 T)

should do.


This could be done simply with

   (by
  '((Lst)
 (mapcar
'((L)
   (or
  (not L)   # Make 'T' from 'NIL'
  (prog # Else top level class
 (while (type (last L))
(setq L @) )
 (last L) ) ) )
(car Lst) )
  sort
  Table )

This assumes that 'Table' is of the form

   (
  (((+Asteroid) (+Asteroid)) (X Y) (prinl aa))
  ...
   )

so that '(car Lst)' is '((+Asteroid) (+Asteroid))'.


What do you think?

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-05 Thread Alexander Burger
Hi Tomas,

 good to know.  Maybe this noLint should be added at the end of
 lib/xml.l?

Not necessary as long as we write 'xml_' as '_xml_'.


  Well, 'Pre' and 'Nl' are indeed unused in 'xml'.
 
 Well, whether they are used or not depends on interpretation:
 lexically they are not used, dynamically they are used; they cannot be
 removed without changing the behaviour of the 'xml' function because
 they provide initial values for the recursive '_xml' function.

Correct. What I meant was that in the way 'lint' looks at it, they are
considered as not used.

If you have

   (de foo ()
  (let N 7 (bar)) )

   (de bar ()
  (inc N) )

you get

   ((foo (use N)) (bar (bnd N)))

while with

   (de foo ()
  (let N 7 (_bar)) )

   (de _bar ()
  (inc N) )

you'll get NIL.

'lint' simply checks for certain conventions.


  There is a convention in PicoLisp that when a function name starts
  with an underscore, it is considered a local function.
 ...
  Shall I keep '_xml_', or would you prefer another name?
 
 I did not know about the convention.  Please keep the new '_xml_'
 name.

OK. BTW, the convention is shortly metioned in doc/ref.html#conv.


 Just a thought: I do not like underscores in names much because it

Yes, me too.

 Wouldn't it be worth using a different prefix, maybe in the picolisp3?

I'm not sure. I feel that it is its ugliness which predestines it to
denote such a local concept.

picolisp3 only addresses the lowest levels of the interpreter, not the
naming conventions.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2009-01-02 Thread Tomas Hlavaty
Hi Alex,

: (lintAll)
- ((order (bnd S)))

I tried it on the multi-method code and got a warning:

(de mmApply @
   (let (N (next)
 A (rest)
 K (mapcar type A)
 Mm (filter '((M) (mmApplicable K (car M))) (get N 'mm)) )
  (ifn Mm
 (quit 'mm (list No applicable method N A K))
 (let mmNext '(()
   (ifn (cdr (pop 'Mm))
  (quit 'mm (list No other method N A K))
  (apply @ A) ) )
(apply (cdr (pop 'Mm)) A) ) ) ) )

: (lintAll)
(lintAll)
- ((mmApply (use mmNext)))

A false positive? ('mmNext' can be called in the function under
'apply'.)  Maybe a dynamically scoped code is impossible to check
reliably?

I also got:

- ((xml (use Pre Nl)) (xml_ (bnd Nn N Pre Nl)) (xmlEsc (use @A)))

when run with the new lib/xml.l loaded.  The xml and xml_ are fine,
xmlEsc looks like it has unused @A.

Thank you,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2008-12-23 Thread Alexander Burger
Hi Tomas,

 the 'sort' function has the less-than relation built-in.  Is there an
 easy way of sorting a list using a user-defined less-than relation?

Well, in a certain way you used it already, with 'by'.


I'm not quite sure about the purpose of

(when (apply Lt NIL X Y)

'apply' does not make much sense here, as the list argument is NIL. I
think that

   (when (Lt X Y)

would do directly what you intend.


However, there is another problem with 'order', probably just a wrong
parenthesis:

  (let S 0
 (for Y Lst
(when (apply Lt NIL X Y)
   (inc 'S) ) ) )
  (push 'Q (cons S X)) )

'S' is unbound when 'cons' is called, so the CARs of all elements end up
with NIL (or whatever 'S' was before).


 That is quite simple but not efficient.

True, as the list is iterated proportional to the square of the length.
Why do you think this is necessary?


 Could the existing 'sort' function be extended for the scenario with a
 user-defined less-than relation?

I decided back then to write 'sort' without a functional argument, as I
believe that it is more efficient this way. If 'sort' calls a function
twice each time two elements need to be compared, it will involve more
overhead than simply applying this function once to each argument before
the call to 'sort'. 'sort' is much simpler this way and does not have to
do any bookkeeping. Built-in list functions can be used better and more
efficiently to do the pre- and post-processing.

'by' already does something similar what you did in 'order'. Let's say

   : (by - sort (6 2 4 7 4 1 3 7 5))
   - (7 7 6 5 4 4 3 2 1)

then 'by' first builds a list

   ((-6 . 6) (-2 . 2) (-4 . 4) (-7 . 7) (-4 . 4) (-1 . 1) (-3 . 3) (-7 . 7) (-5 
. 5))

This is handed to 'sort', which gives

   ((-7 . 7) (-7 . 7) (-6 . 6) (-5 . 5) (-4 . 4) (-4 . 4) (-3 . 3) (-2 . 2) (-1 
. 1))

Then 'by' extracts the CDRs.

Of course, the same thing can be achieved even more efficiently with

   : (flip (sort (6 2 4 7 4 1 3 7 5)))
   - (7 7 6 5 4 4 3 2 1)


What user-defined less-than relation do you have in mind?

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: sort

2008-12-23 Thread Alexander Burger
On Tue, Dec 23, 2008 at 07:15:16PM +0100, Alexander Burger wrote:
 'S' is unbound when 'cons' is called, so the CARs of all elements end up
 with NIL (or whatever 'S' was before).

BTW, such bugs are easily detected by 'lint':

   : (lint 'order)
   - ((bnd S))

This cryptic result means bind 'S'.


It is a good idea to call 'lintAll' from time to time:

   : (lintAll)
   - ((order (bnd S)))

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe