klambda port: list or sexpr+vector

83 views
Skip to first unread message

Richard Man

unread,
Mar 16, 2024, 7:19:12 PM3/16/24
to qil...@googlegroups.com
What's the current best practices for implementing a list for KLambda (in C++)? I can use a simple std::pair linked list, so

(a b c) is really ( a . ( b . (c nil) ) )
of use a sexpr+vector

(a b c) ---> sexpr=a vector=[b, c]

the latter form is equally efficient to get the CAR cell, and space efficient to store many elements in the CDR portion. The downside is that accessing CD means copying the vector and turning the first element into an sexpr.

Also, it doesn't  distinguish between
(a . b) a cons cell vs
(a b) a list

but maybe that doesn't matter in KL

Thanks

--

Bruno Deferrari

unread,
Mar 16, 2024, 7:28:55 PM3/16/24
to qil...@googlegroups.com
The `std::pair` version will work much better.

In Shen, both creating a new list by prepending an element to another list, and accessing the first element of a list or its tail are extremely common operations, both by themselves, and in recursive code (so you will get the head of tail of the tail of the tail.... etc). You want these operations to be efficient.



--
You received this message because you are subscribed to the Google Groups "Shen" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qilang+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/qilang/CAF8hL-FU_%2BdoAnyhahOV798QVbzJ4iLSFhhQ7ODhPqvsk8ZSEw%40mail.gmail.com.


--
BD

dr.mt...@gmail.com

unread,
Mar 17, 2024, 12:31:27 AM3/17/24
to Shen


Also, it doesn't  distinguish between
(a . b) a cons cell vs
(a b) a list

but maybe that doesn't matter in KL

Richard Man

unread,
Mar 17, 2024, 6:26:54 AM3/17/24
to qil...@googlegroups.com
Great, the parser and printer working pretty well now. It uses a C++ GC lib so that part is done as well

richard@file-server:~/codedev/Shen/shen-cpp/shen-cpp$ ./shen-cpp
> (a b c (d e f) g (h i) "hello world" ( 42 3.1415926) )
( a b c ( d e . f ) g ( h . i ) "hello world" 42 . 3.141593 )


--
You received this message because you are subscribed to the Google Groups "Shen" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qilang+un...@googlegroups.com.

Bruno Deferrari

unread,
Mar 17, 2024, 9:26:15 AM3/17/24
to qil...@googlegroups.com
Hi Richard. Based on the printed result, you are missing a () at the end of each of those lists

(d e f) is (d e f . ()) not (d e . f)




--
BD

Richard Man

unread,
Mar 17, 2024, 1:54:27 PM3/17/24
to qil...@googlegroups.com
I am putting the last pair as dotted pair, which is what I thought is the recommended thing to do. Easy to remove if that’s incorrect. 

I don’t see the dotted pair “operator” in the KL syntax page. Do I need to support it then? 



dr.mt...@gmail.com

unread,
Mar 17, 2024, 2:29:37 PM3/17/24
to Shen
There are two separate questions here.

1.  How do you construct dotted pairs in KL?
2.  How do you present, that is, print, dotted pairs in KL?

You've already solved 1.   The syntax of the dotted pair of a and b is (cons a b).  You don't have
 to support any kind of KL printer if you don't want to beyond what is required to implement KL.  
The printing of symbolic expressions is handled in Shen.  See Streams and I/O near the bottom

M.

dr.mt...@gmail.com

unread,
Mar 17, 2024, 4:24:55 PM3/17/24
to Shen
Richard, basically as you know there are character streams and byte streams in most 
languages and streams are either sources or sinks. You can read bytes from a byte source or
write bytes to a byte sink.  Character streams are similar in sustaining sources and
sinks but the currency of transmission is supposed to be characters.  Ontologically
characters can be mapped to unit strings, so KL and Shen don't bother with characters
and just admit strings.

The utility of read-byte and write-byte is that it enables Shen/KL to read from and write to
binary files.  When I wrote Shen I considered that byte streams were the most fundamental
form of stream and that read-byte and write-byte should be sufficient to define all I/O.  

The problem comes when we try to apply this idealistic view to operations to the standard
input and output in existing languages.  In SBCL you can read a byte from standard input but
in CLISP you cannot.  So if the language platform is not understanding of your attempts then
read-byte and write-byte alone will not suffice to get you off the ground.  

I then added these primitive functions

1.  shen.write-string which would write a string to a character-based standard output stream.
2.  shen.read-unit-string which would read a unit string from a character-based standard input stream.
3.  A 1-place primitive function shen.char-stinput? which takes a stream as an argument and
    returns true if it is a character based standard input.
4. An equivalent function shen.char-stoutput? which takes a stream as an argument and returns  
true if it is a character based standard output.
   
I'll break here before continuing on what you have to do.  It's actually a lot easier than what
you are trying to do.

Mark


dr.mt...@gmail.com

unread,
Mar 17, 2024, 4:27:38 PM3/17/24
to Shen
So this is what you have to do.  First you have to determine if the standard input/output is character based or byte based.  It is character based iff it will not support read/write byte.

                                     Character Based?                              
___________________________________________________________________________
Standard Output          yes - step 1                                  
                                     no  - step 2                                  
                           

Standard Input             yes - step 3                                  
                                     no  - step 4                                  
                           
Step 1.

Is your standard output character based?  If so, define shen.char-stoutput? to return true if it is given the standard output as an argument.  Define shen.write-string as a two
 place function that writes a string to a character stream (string first, stream second).  Skip step 2.

Step 2.

Simple.  Define shen.char-stoutput? to return false whatever the input.

Step 3.  

Is your standard input character based?  If so, define shen.char-stinput? to return true if it is given the standard input as an argument.  Define 'shen.read-unit-string' 
that reads a unit string from the standard input.  Skip step 4.

Step 4.

Simple.  Define shen.char-stinput? to return false whatever the input.

That's all you have to do.  Much easier than writing a pretty printer for KL.

There was a private debate about whether these shen dot functions should be part of KL.  The reason they are not is that it is possible that some platforms might not 
need them to get Shen off the ground.  For example, shen.read-unit-string is not needed in SBCL/Shen.

Mark


Richard Man

unread,
Mar 17, 2024, 6:15:17 PM3/17/24
to qil...@googlegroups.com
Thanks Mark. The KL printer is just for my own use to make sure I can parse correctly. I will now move forward with the primitives.

Reply all
Reply to author
Forward
0 new messages