Mostrando entradas con la etiqueta scheme. Mostrar todas las entradas
Mostrando entradas con la etiqueta scheme. Mostrar todas las entradas

martes, 6 de junio de 2017

scripting your .ssh/config with scheme

Generating config files via programs is an old trick which I'm not going to rediscover now. But this one is my first scheme script I wrote for that purpose.

It's about generating a config file you ought to put in your ~/.ssh/config , so that there are some sane defaults when you are ssh-ing to your servers.



It's using the amazon cli interface to fetch the instances of your aws infrastructure. Then, concatenating it with a list of custome servers, and that's basically it (I'm using chicken scheme here, with the regex module which you can get via chicken-install):

With just this, you can already ssh to the servers and have your username filled in, or have your aliases in there.

Also, as I'm super super lazy, I also have a readily available command to prompt me for the server I want to ssh to, and make it ssh there. Quite simple stuff, but hey, it works :)

urxvt -e ssh $(grep 'host ' .ssh/config | awk '{print $2}' | dmenu -l 10)

domingo, 3 de enero de 2016

Continuations as accumulators

Some months ago I read The Little Schemer, an amazing book that guides through many functional programming concepts in a very different way to other books.

To me, by far the most challenging part of the book whas that exercise in page 137 which uses a continuation as an accumulator. I remember being hours staring at it thinking "WTF?". In fact I also remembered that in SICP there was a code example (in the compiler chapter IIRC) that used this style of programming, and also got me puzzled, and I ended up letting it go, and continuing reading (after some time staring at it also).

Months after TLS and years after SICP, I'm reading Concepts, Techniques, and Models of Computer Programming (CTM), and at some point it talks about recursion, and accumulators. At the point it starts explaining multiple accumulators, I had an 'aha' moment, closing the multirember&co problem. In fact CTM doesn't talk about CPS (at least in that part). But somehow intuitively they're talking about the same concept.



def odd_even_part(l, &block)
  if l.empty?
    yield([], [])
  elsif l[0].even?
    odd_even_part(l[1..-1]) do |odds, evens|
      yield(odds, evens + [l[0]])
    end
  else
    odd_even_part(l[1..-1]) do |odds, evens|
      yield(odds + [l[0]], evens)
    end
  end
end

odd_even_part([1,2,3,4]) do |odds, evens|
  puts "odds => #{odds}"
  puts "evens => #{evens}"
end

I decided to reimplement a variant of it in ruby. Now that I look at it, it's super simple... I guess some things just need time to settle.

Here are some related links, talking about the technique or explanations of the original problem.

domingo, 14 de abril de 2013

Embedding Lua, embedding Guile

Lately I've spent a quite few hours hacking on Lua. I love its simplicity, and the way it exposes lots of inner aspects of the programming language, that are usually hidden from the user in other programming languages.

One of the cool aspects of lua is the easiness of embedding it into your C app. But let's make it more fun. Embed Guile also inthere.

Lua

The process to embed Lua in a C app is quite easy, and simple (for really simple things), but I guess it gets more cumbersome when the complexity of the embedding system increases. Being a stack based vm makes it non-trivial to write some embedding functions (recursive functions, for example).

Guile.

The way to embed guile into an app is also, really easy. And Powerful. And you're not bound to interact with it using a stack based machine, but you just register your functions, and use the generic SCM type for all inputs and outputs. I find it easier than Lua

The Code

Here's a minimal example that does some trivial calculations and the flux of the code passes from C to guile, guile calls another C function, and after this, we call lua which also calls a function we have defined in C. In the end it's doing something like (n! + 1).

domingo, 7 de abril de 2013

Guile's deprecation warnings

I've been hacking a bit of Guile (for embedding purposes), and somehow I got to use some deprecated functions: scm_int2num and scm_num2int. The amazing thing is that along with the result of the program, you get the following warning message:
Some deprecated features have been used.  Set the environment
variable GUILE_WARN_DEPRECATED to "detailed" and rerun the
program to get more information.  Set it to "no" to suppress
this message.
Nice, no? Let's set the variable and rerun.
`scm_int2num' is deprecated. Use scm_from_int instead.
`scm_num2int' is deprecated. Use scm_to_int instead.
These kind of things make usin guile a pleasure. Now back to embedding.

lunes, 14 de mayo de 2012

CompGuile. Compile guile in ubuntu

Guile is the Gnu Scheme implementation and official extension language for gnu apps. Let alone most gnu apps disregard this rule. I always found guile a good companion because it was easily instalable in all my linux boxes.

 The other day I tried to install a newer version to work with geiser (and because I had been reading some nice things related to new versions on Wingo's blog), but the installing process wasn't as simple as ./configure && make install. Mostly my fault, because I just needed many *-dev packages that were not present in my box. But after installing gmp and some other easy-to-find libs, I got stuck into "No package 'bdw-gc' found". As jao put in a mail in guile maillist,

"You can tell configure where BDW is located by setting the above
mentioned environment variables. With libgc-dev installed from a deb, i
routinely do (in a bash prompt):

  $ BDW_GC_CFLAGS=-L/usr/lib BDW_GC_LIBS=-lgc ./configure
"   

martes, 8 de febrero de 2011

(let ((there be)) lisp)

I keep having lots of fun with hascheme. In the last couple of
days, I implemented quite a few things. Mostly they are syntax
sugar for things you could already do in HAS, or useful procedures
needed for my basic interpreter testing.


  • Perl side

    • (define (fun args) body) is now accepted as an alternative way
      to declare procedures.

    • (let) implemented. These bindings for local vars are just sintactic sugar for
      what you'd write in perl:
      sub { my $a=shift; … }->(initialval)


  • Scheme side
    Reread the 'Why functional programming matters' paper, and implemented:

    • make-counter, foldr

    • append, sum-list, length, map . All are specific cases of the previous


Reading chapter 4 of our MIT beloved book, I saw the next step, making a lazy
interpreter from this Half Assed one.

Ah, the repo

viernes, 4 de febrero de 2011

QuasiQuine

Little updates to Hascheme, I finally implemented cons, car, cdr,
and list as primitives, After implementing the prove that you can
have datastructures in a language without no more ground than
lambdas, I went for a bit more of efficiency (not that hascheme is
going to be in production ever, but you know…)



Another motivation to implement lists as primitives is that this
way, I can get a kind of homoiconicity. If conses are implemented
in the implemented language (scheme), a list will never be similar
to code, because Perl never sees the datastructure as something it
can deal with.



And what's the ultimate motivation for having all this stuff
working? fun.



I used a very common lisp quine to test that code and data are
implemented internally the same way. That gave a good testbed for
quote too. Unfortunately, using Perl Data::Dump* modules, I can't
tune how lists are printed, and the final nil gets printed too.



Well, here's the proof that Half Assed Scheme can do Half Assed
Quines.




Next step, testing that closures work. (I'm afraid they don't work quite well)

martes, 25 de enero de 2011

(cadr has)

I've been hacking on HAS a bit more, to push forward its functionality.
Mostly what's been achieved by now:


  • Perl side

    • (repl) primitive implemented. it acts as a debugger in some way,
      because it gives you the environment in the state of the moment
      when you executed it. I couldn't implement it in scheme itself
      because I have no eval available from scheme.

    • Read plain files. As I started implementing some functionality
      in scheme, A scheme file must be loaded at start. just enter the
      file name as a parameter. Last sexp should be (repl) to have
      your repl available.

    • Comments. ';' is the comment marker

    • = operator

    • nil. transformed to 0.

    • list. yeah. As HAScheme can't understand variable length
      arguments, I implemented it to make it more confortable to build
      lists. It's built on an ugly hack. More on that later.

  • Scheme side

    • cons, car, cdr. Implemented basic structures. Implemented as
      lambdas. as in SICP, somewhere in chapter 2 IIRC. Simple though
      impressive IMHO (and inefficient, but…)

    • print_list. conses down a list and prints each element in a
      line

I run it using builtins.scm as the first parameter, and then, repl is
yours, with lists and conses available for you.

Now the not-so-beautiful parts


If I want lists, I just have to nest conses, but who doesn't want a
litte luxury?.

To implement list, I've thought 3 possible solutions (haven't read

about how to implement them correctly, just brainstorming):


  • Variable actual arguments. If I could implement the dot (.) syntax
    for variable number of arguments, I could implement list as a
    simple scheme function. Problem is that I need lists to stash
    the resting parameters (hascheme lists, not Perl ), and I haven't thought how to bootstrap.

  • Write a new primitive (on the perl side) that builds the correct
    cons structures, on the perl side. Mind you, that list is VERY
    coupled to cons implementation. And quite fuzzy on the perl side
    too.

  • Substitute list for the appropiate number of conses (as a string),
    and let the already written parser do the job. That's the one I implemented.

Probably, I'll start from the scratch building another scheme interpreter, following BillHails book. Or at least, I'll go as far as my motivation and brain allow me.

That's all for now. Here's my other post about Hascheme, and the github repo.

Byez.

domingo, 23 de enero de 2011

I can has HAS (Half Assed Scheme)


If you've been reading along these bloglines, you already know I'm on
my way to learn lisp, and given that a typical exercise on the lispers
path is writing a scheme interpreter, I decided to try to impement a
scheme interpreter in perl. I had a great guidance of Peter Norvig's lispy tutorial, and more thoughtful explanations from Bill Hails' book.




I can't say I wrote it as quick as I thought I would, and it could
definately be clearer (OOP in such small projects is clearly
overengineering), but in the end, it works, and given the fact that I
hadn't been programming perl at work for 2 months, it's been a good exercice.



The relevant code is in 4 files,


  • script/lis.pl (REPL and primitives),

  • lib/hascheme/Reader.pm (Parsing)

  • lib/hascheme/Env.pm (environment, a tree structure built on hashes)

  • lib/hascheme/Evaluator.pm (special operators are treated here, and overall evaluation)



Anyway, here you are, the code is in a github repo. For now, It's
called half assed scheme, or hascheme, or HAS.

Related article: next post on HAS


Now, you can has HAS too.

lunes, 16 de agosto de 2010

Memoizer in common lisp

Last weekend I finished a fast-read of Ansi Common Lisp. I didn't do the exercices but I did pay attention to code examples (those are what make me really understand things).

Overall I find it pretty good, but a bit simple provided you already know something related to the lisp world.

After finishing it, I tried a couple of tricks in lisp, and was surprised how easy it was to come with working codes of a memoized function. Once you have a memoized function, why not convert it to a memoizer function?

Here it is. (If you're reading it on google reader you won't be able to see it, better read blogposts from the original site)




(setf memofib (memoizer #'fib))
(funcall memofib 10)

And you have now a faster fib than before.

Question: how should I change it to make a generic memoizer that memoizes not only unary functions.
In perl I'd have to just pass @_, I suppose changing arg to '&rest arg' and change funcall to apply would do the trick... I have to try it. Later.

More readings: Scheme R5RS.
I read the part I hadn't read before. I have to say even the scheme spec is minimalist, well written, and didactic. Following the language philosophy even at docs level. :)

And a bit more: A paper on Scheme macros. I think I get them, but I don't see much use for them. I suppose I'm still an average blub programmer.

martes, 13 de julio de 2010

Back to the future?

9:00
Llego al currele, y mientras estoy haciendo mi navegacion de
reconocimiento, encuentro porahí un link interesante: Google’s
Do-It-Yourself App Creation Software
. Alguna frikada de google
labs... ya verás. Total, que empiezo el articulo y leo que el
proyecto esta liderado por un tal "Harold Abelson". H.Abelson en
google? (pues se ve que se ha pillao un sabático del MIT). Bueno, el
proyecto va encaminado a que todo el mundo pueda ser programador de
sus miniaplicaciones.

17:00
Recibo un mail en una maillist Que pone "se nos acabóo el trabajo".
Coño! Esto es scratch!!!
Reflexión: Los Schemers chupando de smalltalk? Bueno, puede ser,
entre comunidades pioneras... pero en google, hacen algo en
scheme/smalltalk? Bueno, de hecho, scratch tambien sale del MIT, creo.

17:30
Llego a la pagina oficial del proyecto y efectivamente al final de la pagina.
(...) Open Blocks visual programming is closely related to the Scratch
programming language, a project of the MIT Media Laboratory's Lifelong
Kindergarten Group.

The compiler that translates the visual blocks language for
implementation on Android uses the Kawa Language Framework and Kawa's
dialect of the Scheme programming language, developed by Per Bothner
and distributed as part of the Gnu Operating System by the Free
Software Foundation. (...)

18:00
Me pregunto si contestar al mail de la maillist contando de donde
viene todo esto, quien es Abelson, y entro en otra
batalla épica? Respondo con un : "joer, estos de google son la ostia,
estas cosas, solo las pueden inventar ellos...", me callo?.


En fin... Esta claro que poco a poco van alcanzándonos, pero la
verdad es que me encanta estar en este mundillo (pionero después de
casi 30 años), y estas aproximaciones que hacen 'los grandes' le dan a
uno la confirmación de la sospecha: "yeah, voy un paso por delante,
que se jodan" :D

lunes, 29 de marzo de 2010

Scheme and home-made objects

Scheme is functional. Functional and minimalist.

But its power to build higher abstractions with the basic toolset it provides, allows us to build a pseudo Object oriented system by ourselves.

That's what SICP 3.1 - 3.4 exercices are about:

Using the closure property we have learnt about in chapter 2, and the just revealed set! function, we can build objects with private state to the world.

We'll use the classical bank account exercice. We create it with a initial amount of money and we can deposit money and withdraw money (iif we have enough money there).

At the end of the 4 exercices we should have a way to generate password protected bank accounts, which remember not only the password but how many wrong passwords you have entered in a row. If you fail thrice, it'll call the cops.

To solve this little problem (that, on the other hand I love because of its well defined objectives and dose of reality) we'll first have a make-monitored function, that counts how many times it's been called. make-monitored procedure gets a procedure as a parameter, and outputs a prodecure that is like the one entered, but with the counter stuff added. we could say it makes wrapped functions (decorated if you come from python).

The password protected account uses just an extra local variable to the closure that has the password.



the usage is like

(define pw-acc (make-protected-account 'secretp4ss 100))
((pw-acc 'secretp4ss 'deposit) 10) => ok
((pw-acc 'wr0ngpass 'deposit) 10) => fail
((pw-acc 'wr0ngpass 'deposit) 10) => fail
((pw-acc 'wr0ngpass 'deposit) 10) => call-the-police


I don't like that when a wrong pass is passed as an argument, the output is applied to the argument (10 in this case), and scheme doesn't know how to apply it.

I've worked partial solutions but none convinced me one being flattening the way to call the functions (pw-acc 'pass 'deposit 10) but this way, the password protected account had to know about how many parameters received each function. The other solution is returning a dummy functions that accepts one parameter in case of wrong password. Unfortunately, here we just accept 1 parameter, so we are limited too.

Any suggestions are very welcome

sábado, 27 de febrero de 2010

Mastermind in scheme. Now with GUI!!


plt scheme has a wide collection of libraries, some bundled with the basic package, and some which have to be installed through PLaneT.

GUI library is from the first group, so if you have plt-scheme already installed (not mzshceme alone, but the complete suite, with drscheme and so) you already have everything you need.

WARNING: It seems there's some programming course in NY with an assignment related to writing a mastermind. If it's your case, please, do not use my code blindly. I'm a novice scheme programmer, and probaly, my code is not very idiomatic. Anyway, have fun.

I've been using the mastermind game as a toy project to learn scheme for the last month. And now, it even has a little GUI. I also have a solver in 5 tries (in the worst case) but I haven't embedded it yet in the GUI.

The process of writing GUIs using plt-scheme is easier than I thought. It's great to write little things (we could say it makes easy things really easy). I don't know how difficult it'd be to write a more complex GUI, for example, I haven't found any grid component. Only comboboxes, radiobuttons, buttons and text-fields.

The good part is that it's really easy to assemble these compoonents in layouts, panels, frames, and so. It's also really easy adding menus to windows.

Here follows a little code that lets you play mastermind, fully coded in scheme.



Btw, This is (more or less) what I used last wednesday at flibug meeting to show an example of GUIs in plt. I really enjoyed the meeting: Learning, sharing, having fun, and beers :) .There's some more info about the last flibug meeting in my last post.

viernes, 26 de febrero de 2010

lisperlang

This has been a frenetic week. It seems that flibug and Perl Mongers meet at the same week every month.

But first things first.

Monday: Erlang.

I attended to the first class of an introductory erlang course. For the moment, we only looked at erlang syntax (btw, it sucks), and some points of functional programming. Pattern matching, tail recursion, consing, lists, and some erlang's BIFs to manage lists (we have neither while nor for). I'll expand a bit more on erlang on a future post.

Wednesday: Flibug.

A small and familiar meeting. Thomas H. Marc-André L., Andrew B., Andy W and me. As always, we talked about what we are hacking on lately and did some lightning talks.

  • I did my first lightning talk, about making GUIs using plt-scheme. A bit simple for the general level of flibug talks, but well, I think it's a good way to start doing talks. And probably, Thomas will do a talk next month on an alternative way to write GUIs in scheme. I'll post about it in a future post.
  • Andrew B. talked about an app he did some time ago in OCaml to apply morphologic filters to images. Pretty interesting but I couldn't understand the details. All in all, I think I got a good overview and I got 'the message': "functional pays off more times than we think".
  • Wingo showed us some interesting parts of guile code. Mostly the evaluator, and he explained us the multilevel scheme compiler/interpreter (c -> scheme -> scheme). He also showed us the guile-gtk bindings.
Great meeting, as always, and it makes you feel like hacking more and more.

Thursday: Breakout && Barcelona Perl Mongers.

After $work, I went to borneo bar, the place where this month's Breakout was held. Some chitchat while having lunch with other smalltalkers, then some hacking, and at 20:00, we had a PerlMongers meeting.
  • Alexm brought some round tuits for us. He explained some of his experiences at last FOSDEM.
  • Esteve did a talk about FluidDB implementation and it's intended usage. Pretty cool stuff, and little by little, I think I start to understand the amplitude of the concept.
  • Fxn ended the session with a talk on his Net::FluidDB module, and the difficulties he had to coerce floats,ints and booleans between fluiddb and Perl. He talked about some Perl internals I didn't know. And he's a great speaker, so it's always a pleasure to hear.
  • It was probably the most crowded PM meeting I've been to. It was a really great meeting.

You see... pretty busy week, isn't it? Well, in fact, at $work I've been busy too, reading about evolving graphs in genetic algorithms. I've done some literature fetching on GA parallelization.

Conclusion
My brain's gonna explode in 5, 4, 3, 2,.... Ah no, I'm just in coma.

Meta
Btw, when writing this post, I've started a new tiny tool which I called LinkAdder, that's just intended to add some common html links I insert over and over on my posts. Its repo is here. It's a very simple translator for now, but I have some ideas for it.

sábado, 23 de enero de 2010

permutations with repetition in scheme

With my exams finished and my final project at uni also finished, I had some time to spend with my already-started-but-not-finished small coding challenges.

As you may know, some time ago I started not one but two implementations of mastermind.

One in Perl, and the other in Scheme.

I wanted to finish the scheme implementation, so I started to look at Donald Knuth's paper about Mastermind. It's not so complicated, but as I've been far from complex algorithms for some time, it scared me a bit.

First thing to do is having available all possible combinations (strictly speaking they are permutations as order matters) of colours (in our case numbers). Two nested maps, a recursive call, and you're done.

As I don't have time to comment all the code, I'll just post here the permutations part, and keep the complete code private for now. When I have the time, I'll post it all, with appropiate comments. It's a minimax algorithm, so not daunting at all, but....

Here it is:



Apart from this, I've hacked with a few things (as time permitted). If you're specially interested in something, ask.

  • net sniffing
  • Image analyzing and video tracking
  • html parsing and web scraping

domingo, 13 de diciembre de 2009

info is power

In planet emacs, I discovered that there's a version of SICP in info format.

If you don't know what's SICP, it is a computer science book about programming fundamentals, that teaches you how to think about programming, and algorithms in general.

I'm reading it little by little because there are many deep concepts that I need to interiorize with some extra time and rereads. The book is freely available in html format. There are other sites that offer a pdf version, but this info version at http://www.neilvandyke.org/sicp-texi/ , sounds like a great option, because I'll be able to read it in any info pager, without relying on slow pdf viewers, or having to be online and use a browser.

after downloading the sicp.info.gz file , I installed it moving the file to a info suitable place (/usr/share/info and /usr/info are good places for vectorlinux).

To make it available from info's top menu, you should add a link line in the 'dir' file, or you can use intall-info.

As I had my info 'dir' file somewhat outdated, that's what I did to rebuild the whole dir:
for i in $(ls /usr/info/*) do install-info $i /usr/info/dir
now, when I type "info" in my command line, I get a 2362 line info index and among library infos and so, there's
* SICP: (sicp). Structure and Interpretation of Computer Programs


Sorry, no puns, no music links, no OMFGWTFORLYFAIL links today.

viernes, 27 de noviembre de 2009

Mastermind setter (scheme) and flibug meeting

Mastermind setter
Last week, I couldn't work on the mastermind solver, but at least, I finished the setter.

It was a good exercice to get in touch with scheme IO, like getting input from user, split strings, and the like.

I finally removed all the functions for IO, because I can supply the inputs as lists on the REPL. I've used drscheme, but as this week I also tried guile (embeding it in a c app. Pretty cool), I might try it for future hacks.
(check-sols '(1 2) '(1 3))

I'm quite excited about how easy it became to do it, and this weekend I'll spend some time on the solver.

flibug
On the other side, this tuesday we had another flibug meeting at oblong. Amazing, as always:
  • Aleix Conchillo made a live presentation about plt slideshow. A module to create slides using scheme. Given that I had invested some time to find a good slides maker and not finding it, this might be a good solution to study further.
  • Andy Wingo showed us a demo of the greatest technology I've seen in many many many (sorry) months. When I arrived home I said "Papa,mama, I'm back from the future".
  • Colin Fleming made a good (also with live demos) presentation about IntelliJ refactoring tools, and he expressed his feeling of the need for clever programing environments. It's impressive how an IDE parses your code, and how much it knows about good/bad practices and hints you with improvements. He started coding a scheme mode for this IDE that already managed some refactorings like var renaming. As editors are a religion matter, some of the assistants had a few doubts of the real benefits of using a 'cool' boxed IDE (although extensible) versus using a swissknife-and-the-kitchen-sink emacs. On my part, being a vim user for 4 years and just starting to dip in emacs, I'll follow this thread really close.
I'd like to thank all the flibuggers and oblong for sharing all that coolness. I wish I could share more with them giving something back (with a presentation). Maybe when I finish my degree project I can prepare something about stumpwm or fluxus.

I'd say it's been a pretty exciting scheme-y week.

sábado, 21 de noviembre de 2009

Mastermind in scheme

3 Days ago I read a post on programming praxis blog about writing a mastermind
game. The author splitted the game in two parts, the first
being the setter
, so given a known solution, and a guess, returns a string
of B/W/.

The point is that when I tried to code it, I was in an internetless bar, so I
had to guess some parts of the exercise and I missunderstod some of the points
and the code didn't work as expected (but at least, I succeeded to make it work
as I thought it had to work)

When looking the solution proposed at programming praxis, I payed attention to
both the algorithm used, and the code.

The algorithm used is works calculating white pegs, and then substract black
pegs. Finally, it sorts the black and white pegs and prints the output.

I'll try to write my own version in near future, but, for the moment, I have
updated the perl Mastermind code I started some time ago, that until now, it only compared the solution to the given combination, and returned a good/bad value. Now it uses that algo to tell how accurated is your guess. It's still far from functional, (it only plays random (with or without repetitions (using a cache))), but I have little time to hack on those projects.

I will have to take a look at the programming praxis "standard prelude", where the author shows some generic functions that are used over his solutions.

Btw, Programming Praxis has been one of my last findings on the intertubez. A great find IMHO.

viernes, 20 de noviembre de 2009

Implement a scheme intepreter in X

It might be just a strange coincidence, but lately, every week I discover a new book/tutorial that guides you through writing a scheme interpreter in whatever language I look.

Theres's SICP , implementing scheme in scheme

Theres PLAI , implementing a variant of scheme in a variant of scheme

Also, there's "Exploring programming language architecture in Perl". A book that covers the implementation of a scheme interpreter in perl.

And now here's a new kid in the block I just discovered. Implementing a simple scheme interpreter in haskell. I'll leave it here, and see if I have some time in the near future to read it (I doubt I implement it as I know nearly no haskell)

So many good books to read and so little time and attention span....well, there's still hope on SICP and EPLAiP.

lunes, 16 de noviembre de 2009

Implementing list functions in scheme

I've been messing a bit with scheme lately, and one thing I want to get well is list mangling. As you know, lists are the most basic and pure datastructure in scheme (and I think they are the only true datastructure in scheme).

This is why I want to get them right, and I'm rewriting some basic functions related to lists.

First of all, a little explanation of lisp lists in general.

Lists are based on a more simple structure called "cons". A cons is just a pair. The only thing that can contain a cons in the first (car) or the second (cdr) cell are:
  • string
  • number
  • symbol
  • cons
Yeah, pretty simple, right? The funny thing is that with cons containing conses, we can write all kind of datastructures.

First we'll see two axioms that must always be true related to conses.

(= x (car (cons x y)))
(= y (cdr (cons x y)))

Everything that guarantees this is a cons. Well, at least at this level...

a cons is represented by (x . y) , and a cons with another cons in the cdr would be (x . ( y . z))

A list is a special kind of cons with a determined structure.

( x . (y . (z . nil))) . A way to visually simplify this is ( x y z ) . That means that in a list of n elements, there are n conses linked through cdr's, with the last cdr pointing to nil. If you had to build (1 2 3) with conses, you could do it with (cons 1 (cons 2 (cons 3 nil))) .

Here I show the few scheme functions I wrote along with some explanations that davazp kindly gave me at #emacs-es and #lisp-es.

Theese are my first versions of some functions.




Here we see build-list can be abstracted to a more general (and easier to write) procedure called build-range, and I just call it with a start point = 1.

On the reverse function, we can use a different "happy idea".



Enough for today. Thanks to davazp and other #emacs-es -ers for their help and motivation.