The lfe command

98 views
Skip to first unread message

Robert Virding

unread,
May 21, 2014, 8:18:02 PM5/21/14
to lisp-flavo...@googlegroups.com
I have been thinking of rewriting the 'lfe' command for starting LFE. Now it behaves pretty much in the same way as the 'erl' command when it comes to handling arguments as it almost directly calls 'erl'. So the

My idea is to make 'lfe' behave like bash/sh. So it will first process the options/flags and their arguments, then:

- If there are more arguments then the first one will be assumed to be the name of a script file containing LFE shell commands and the remaining arguments will be passed into the script file. One idea is to bind the variable ProgName to the file name and Args to a list of all the remaining arguments. The commands in the script file will be executed and the LFE will then terminate.

- If there are no more options it will start the LFE shell in interactive mode.

Maybe we should even have it reading and executing commands from a ~/.lferc file?

By being a little cunning we should also be able to use it as executable scripts as well, pretty much like sh.

I had planned to leave lfescript as is as it matches escript and has been around for a while.

This is about as far as I got so far. I will fix test versions so we can experiment and see if it useful and get it working properly.

Robert

Duncan McGreggor

unread,
May 22, 2014, 1:41:02 AM5/22/14
to lisp-flavo...@googlegroups.com
Just a quick note: I'm fairly excited about this, as I love using LFE for my scripting needs as well as application ones :-)

d

Robert Virding

unread,
May 29, 2014, 2:35:28 PM5/29/14
to lisp-flavo...@googlegroups.com
The way 'erl' handles arguments is a bit strange. It has "flags with args" and plain arguments. So if we have the input:

erl p1 -a -b 3 4 -c -- p2 p3 -m n o p -q 5 6 -- p4

it will be grouped as

erl p1 {-a} {-b 3 4} {-c} -- p2 p3 {-m n o p} {-q 5 6} -- p4

where the {} are the flags + args and p1-p4 are the plain arguments. The -- is interpreted as the end of a flag + args. So you can intermix flags and plain arguments.

My current suggestion for lfe to handles arguments is more unix command like. So everthing from the first "plain" argument become plain arguments. So the input

lfe -a -b 3 4 -c --  p1 p2 p3 -m n o p -q 5 6 -- p4

will be interpreted as

lfe {-a} {-b 3 4} {-c} --  p1 p2 p3 -m n o p -q 5 6 -- p4

where the {} will be flags to erl and everything from p1 onwards will processed by LFE. The idea is that p1 is the name of an LFE script which will be invoked with arguments p2 p3 ... . How the script interprets the arguments is of course up to it. For the moment the LFE has the variable Prog bound the script name, "p1" in this case, and Args bound to a list of arguments, ("p1" "p2" "p3" "-m" "n" "o" "p" "-q" "5" "6" "--" "p4") in this case.

Robert

Duncan McGreggor

unread,
May 29, 2014, 2:38:37 PM5/29/14
to lisp-flavo...@googlegroups.com
Yeah, I definitely like this.

d


--
You received this message because you are subscribed to the Google Groups "Lisp Flavoured Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.
To post to this group, send email to lisp-flavo...@googlegroups.com.
Visit this group at http://groups.google.com/group/lisp-flavoured-erlang.
For more options, visit https://groups.google.com/d/optout.

Robert Virding

unread,
May 29, 2014, 2:54:43 PM5/29/14
to lisp-flavo...@googlegroups.com
All that is left is to decide which language to write it in. sh is easy but handling the args can lead to the need for complex quoting when writing the calls. Args with spaces in them are messy to get right. With C that is easy and the code is not much more difficult either.

Robert
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-erlang+unsub...@googlegroups.com.
To post to this group, send email to lisp-flavoured-erlang@googlegroups.com.

Duncan McGreggor

unread,
May 29, 2014, 3:14:27 PM5/29/14
to lisp-flavo...@googlegroups.com
Yeah, that's tricky... I'm facing something similar with lfetool. I've even considered taking on the work of converting it to lfescript ;-) (with a bootstrapping phase).

Bash will be faster than C (for the things I've measured in the past, anyway). But who's counting milliseconds with this sort of thing? I'd go for what is going to be easier to maintain in the long run ...

d



To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.
To post to this group, send email to lisp-flavo...@googlegroups.com.

Robert Virding

unread,
Jun 1, 2014, 6:24:11 PM6/1/14
to lisp-flavo...@googlegroups.com
I did discover a way to get arrays into classic sh which doesn't have arrays: you can the positional parameters as a circular buffer/array. And if you use set to append a new element then you don't get problem of appending a string. So

set -- "$@" $newvalue

will append $newvalue to the "array" without problems. And then shift to remove elements from the head. Of course you can only prepend or append values, but appart from that it works like a charm. Look in the lfe-dev branch at lfe-1 and lfescript for examples.

Robert

Duncan McGreggor

unread,
Jun 13, 2014, 6:01:21 PM6/13/14
to lisp-flavo...@googlegroups.com
Hey Robert, 

Just wanted to give you a heads-up that I'll be experimenting with this branch in the lfetool rewrite -- so you'll probably start seeing lots of questions from me!

d


--

Robert Virding

unread,
Jun 15, 2014, 6:05:27 AM6/15/14
to lisp-flavo...@googlegroups.com
From the discussions we had at our LUG (LFE user group, or perhaps LFEUG?) meeting I assumed that people approved of the "new" way for the lfe and lfescript to handle arguments. So I will add these ideas into the standard 'develop' branch soon.

Robert


On Saturday, June 14, 2014 12:01:21 AM UTC+2, Duncan McGreggor wrote:
Hey Robert, 

Just wanted to give you a heads-up that I'll be experimenting with this branch in the lfetool rewrite -- so you'll probably start seeing lots of questions from me!

d
On Sun, Jun 1, 2014 at 3:24 PM, Robert Virding <rvir...@gmail.com> wrote:
I did discover a way to get arrays into classic sh which doesn't have arrays: you can the positional parameters as a circular buffer/array. And if you use set to append a new element then you don't get problem of appending a string. So

set -- "$@" $newvalue

will append $newvalue to the "array" without problems. And then shift to remove elements from the head. Of course you can only prepend or append values, but appart from that it works like a charm. Look in the lfe-dev branch at lfe-1 and lfescript for examples.

Robert


On Thursday, May 29, 2014 9:14:27 PM UTC+2, Duncan McGreggor wrote:
Yeah, that's tricky... I'm facing something similar with lfetool. I've even considered taking on the work of converting it to lfescript ;-) (with a bootstrapping phase).

Bash will be faster than C (for the things I've measured in the past, anyway). But who's counting milliseconds with this sort of thing? I'd go for what is going to be easier to maintain in the long run ...

d



On Thu, May 29, 2014 at 11:54 AM, Robert Virding <rvir...@gmail.com> wrote:
All that is left is to decide which language to write it in. sh is easy but handling the args can lead to the need for complex quoting when writing the calls. Args with spaces in them are messy to get right. With C that is easy and the code is not much more difficult either.

Robert

--
You received this message because you are subscribed to the Google Groups "Lisp Flavoured Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-erlang+unsub...@googlegroups.com.
To post to this group, send email to lisp-flavoured-erlang@googlegroups.com.

Duncan McGreggor

unread,
Jun 15, 2014, 4:58:09 PM6/15/14
to lisp-flavo...@googlegroups.com
On Sun, Jun 15, 2014 at 3:05 AM, Robert Virding <rvir...@gmail.com> wrote:
From the discussions we had at our LUG (LFE user group, or perhaps LFEUG?)

Hehe. Pronounced "Liffy-oog" ;-)
 
meeting I assumed that people approved of the "new" way for the lfe and lfescript to handle arguments. So I will add these ideas into the standard 'develop' branch soon.

Nice. The only thing I ran into when attempting to use lfe-1 with code that was previously using lfe, was that the expected lfexec wasn't found. I'm guessing that's part of the cleanup you have planned before merging, though.

d
 
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.
To post to this group, send email to lisp-flavo...@googlegroups.com.

Robert Virding

unread,
Jun 15, 2014, 5:55:50 PM6/15/14
to lisp-flavo...@googlegroups.com
Next version complete and now pushed into the latest commit in 'develop' branch. The 'lfe-dev' will soon be deleted.

Both lfe and lfescript take arguments in the form

lfe [-flag1 val1 val2 -flag2 --] script-name script-args

(script-name and script-args are optional in lfe of course). If you use flags you MUST end them with a -- or -extra. Lfescript checks for shebangs in the same style as escript, i.e. a comment in line 2 or 3 starting with ;;! where the rest of the line becomes flags for the erl command. This is not done for the script in the lfe command but I have been thinking of including that as well.

With the new lfe command there is practically no need for lfescr

Robert Virding

unread,
Jun 15, 2014, 6:06:46 PM6/15/14
to lisp-flavo...@googlegroups.com
Re-posting, firefox sometimes hangs and hides what I have written without giving me anyway to access it.

Next version complete and now pushed into the latest commit in 'develop' branch. The 'lfe-dev' branch will soon be deleted.


Both lfe and lfescript take arguments in the form

lfe [-flag1 val1 val2 -flag2 --] script-name script-args

(script-name and script-args are optional in lfe of course). If you use flags you MUST end them with a -- or -extra. Lfescript checks for shebangs in the same style as escript, i.e. a comment in line 2 or 3 starting with ;;! where the rest of the line becomes flags for the erl command. This is not done for the script in the lfe command but I have been thinking of including that as well.

The goal of the new lfe command is to be like sh and there is practically no need for lfescript unless you want to compile the module (which you can't do yet anyway :-))

In the bin directory there is lfe, lfec and lfescript plus lfe-test and lfeexec. They are made to be linked to from your bin directory and not copied into it. If you do copy them they won't work. This will make installing easier but more sensitive.

What also needs to be fixed is how the lfe command line arguments should past into the script. Now there are two shell variables: Prog which contains the name of the script and Args which contains a list of the script arguments. Pretty much like sh $0 and $@. Open to suggestions on this.

Robert

Robert Virding

unread,
Jun 15, 2014, 6:08:27 PM6/15/14
to lisp-flavo...@googlegroups.com
P.S. lfe-test and lfeexec are an experiment using a C program, lfeexec, to handle the arguments.

Duncan McGreggor

unread,
Jan 9, 2015, 10:58:06 AM1/9/15
to lisp-flavo...@googlegroups.com
Wanted to do a quick follow-up to this post and let you know that I've been using ./bin/lfe much more lately, in particular, using lfe -eval '(...)' to replace previous usage of erl -eval '...' and am completely loving it. No issues so far.

d

--

Duncan McGreggor

unread,
Jul 22, 2015, 1:03:13 PM7/22/15
to Lisp Flavoured Erlang
Quick follow-up below:


On Sunday, June 15, 2014 at 5:06:46 PM UTC-5, Robert Virding wrote:
Re-posting, firefox sometimes hangs and hides what I have written without giving me anyway to access it.

Next version complete and now pushed into the latest commit in 'develop' branch. The 'lfe-dev' branch will soon be deleted.

Both lfe and lfescript take arguments in the form

lfe [-flag1 val1 val2 -flag2 --] script-name script-args

(script-name and script-args are optional in lfe of course). If you use flags you MUST end them with a -- or -extra. Lfescript checks for shebangs in the same style as escript, i.e. a comment in line 2 or 3 starting with ;;! where the rest of the line becomes flags for the erl command. This is not done for the script in the lfe command but I have been thinking of including that as well.

The goal of the new lfe command is to be like sh and there is practically no need for lfescript unless you want to compile the module (which you can't do yet anyway :-))

In the bin directory there is lfe, lfec and lfescript plus lfe-test and lfeexec. They are made to be linked to from your bin directory and not copied into it. If you do copy them they won't work. This will make installing easier but more sensitive.

What also needs to be fixed is how the lfe command line arguments should past into the script. Now there are two shell variables: Prog which contains the name of the script and Args which contains a list of the script arguments. Pretty much like sh $0 and $@. Open to suggestions on this.

Not sure if anyone else is using this, but I've started running more scripts with lfe. From inside the script, to get the name of the script that you called and any arguments you passed to it, you have the following variables available:

 * script-name
 * script-args

Duncan McGreggor

unread,
Jul 22, 2015, 1:15:27 PM7/22/15
to Lisp Flavoured Erlang
Some more notes:


On Wednesday, July 22, 2015 at 12:03:13 PM UTC-5, Duncan McGreggor wrote:
Quick follow-up below:

On Sunday, June 15, 2014 at 5:06:46 PM UTC-5, Robert Virding wrote:
Re-posting, firefox sometimes hangs and hides what I have written without giving me anyway to access it.

Next version complete and now pushed into the latest commit in 'develop' branch. The 'lfe-dev' branch will soon be deleted.

Both lfe and lfescript take arguments in the form

lfe [-flag1 val1 val2 -flag2 --] script-name script-args

(script-name and script-args are optional in lfe of course). If you use flags you MUST end them with a -- or -extra. Lfescript checks for shebangs in the same style as escript, i.e. a comment in line 2 or 3 starting with ;;! where the rest of the line becomes flags for the erl command. This is not done for the script in the lfe command but I have been thinking of including that as well.

The goal of the new lfe command is to be like sh and there is practically no need for lfescript unless you want to compile the module (which you can't do yet anyway :-))

In the bin directory there is lfe, lfec and lfescript plus lfe-test and lfeexec. They are made to be linked to from your bin directory and not copied into it. If you do copy them they won't work. This will make installing easier but more sensitive.

What also needs to be fixed is how the lfe command line arguments should past into the script. Now there are two shell variables: Prog which contains the name of the script and Args which contains a list of the script arguments. Pretty much like sh $0 and $@. Open to suggestions on this.

Not sure if anyone else is using this, but I've started running more scripts with lfe. From inside the script, to get the name of the script that you called and any arguments you passed to it, you have the following variables available:

 * script-name
 * script-args


Note that the script as a whole is executed; it's not like using lfe -s <module> where a start/0 function is called, nor using lfescript, where a main/1 function is called. You'll need to call your desired function at the end of the script.

Here's a convention I've started using:

 * define all my functions
 * define a main/n with as many args as expected
 * define a main/1 that inserts defaults and/or does pattern matching on the script args (calling main/n)
 * define a main/0 like so:

(defun main ()
  (main script-args))

And then, at the end of the script file, simply do:

(main)

Hope this helps,

d

Robert Virding

unread,
Jul 22, 2015, 5:28:24 PM7/22/15
to Lisp Flavoured Erlang, dun...@mcgreggor.org


On Wednesday, July 22, 2015 at 7:15:27 PM UTC+2, Duncan McGreggor wrote:
Some more notes:

Not sure if anyone else is using this, but I've started running more scripts with lfe. From inside the script, to get the name of the script that you called and any arguments you passed to it, you have the following variables available:

 * script-name
 * script-args


Note that the script as a whole is executed; it's not like using lfe -s <module> where a start/0 function is called, nor using lfescript, where a main/1 function is called. You'll need to call your desired function at the end of the script.

Here's a convention I've started using:

 * define all my functions
 * define a main/n with as many args as expected
 * define a main/1 that inserts defaults and/or does pattern matching on the script args (calling main/n)
 * define a main/0 like so:

(defun main ()
  (main script-args))

And then, at the end of the script file, simply do:

(main)

That's almost like what you do for lfescript :-). With a bit of cunning you could run it in both, though I don't know why you would want to. Perhaps when I fix lfescript so it compiles the module.

Robert
Reply all
Reply to author
Forward
0 new messages