[ANN] p5scm 0.1.0

Hello,

I’ve released p5scm which is now up on opam. It is a scheme-like implementation on top of camlp5's pa_schemer.ml extension. I know that camlp5 isn’t the cool kid on the block these days but it is a powerful tool and pretty cool in my estimation ;-).

Enjoy,
Jason

6 Likes

This looks neat; do you have any plans to add a macro facility? I would love to have an untyped metaprogramming option available, for those (many, many, many) times such a thing would be useful, but not so useful as to spin up a new ppx.

Nice idea, but no pasarán for me,

opam install p5scm
[ERROR] No package named p5scm found.

opam --version
2.0.8

ocaml --version
The OCaml toplevel, version 4.13.1

git clone , gmake log,
gmake
dune build --profile release @install @runtest
File “src/lib/dune”, line 13, characters 61-67:
13 | (libraries sexp_pretty compiler-libs compiler-libs.common camlp5)
^^^^^^Error: Library “camlp5” not found.
Hint: try:
dune external-lib-deps --missing --profile release @install @runtest
make src/lib/exparser.{ml,mli},src/lib/pa_scheme.ml,src/lib/pconfig.ml,src/lib/pr_dump.ml,src/lib/pr_o.ml (exit 1)
(cd _build/default/src/lib/camlp5 && /usr/bin/make)
cppo pa_schemer.cppo.ml -o pa_schemer.ml
camlp5 pa_r.cmo pa_rp.cmo pa_extend.cmo q_MLast.cmo pr_o.cmo pa_schemer.ml -o …/pa_scheme.ml
File “pa_schemer.ml”, line 639, characters 31-52:
Unbound quotation: “extended_longident”
*** Error code 2
Stop.
make[1]: stopped in /usr/home/x/p5scm/p5scm/_build/default/src/lib/camlp5
gmake: *** [Makefile:6: build] Error 1

dune --version
2.9.1

uname -a:
FreeBSD 13.0-RELEASE-p5

cc -v:
FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
Target: x86_64-unknown-freebsd13.0
Thread model: posix
InstalledDir: /usr/bin

opam install ocamlp5
[ERROR] No package named ocamlp5 found.
HOST:x: /home/x/camlp5/camlp5 >opam install camlp5
The following actions will be performed:
∗ install conf-perl-string-shellquote 1 [required by camlp5]
∗ install conf-perl-ipc-system-simple 1 [required by camlp5]
∗ install camlp5 8.00.02
===== ∗ 3 =====
Do you want to continue? [Y/n] y

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[camlp5.8.00.02] found in cache
Processing 3/3:

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[ERROR] The compilation of conf-perl-ipc-system-simple failed at “/usr/local/bin/perl -MIPC::System::Simple -e 1”.
[ERROR] The compilation of conf-perl-string-shellquote failed at “/usr/local/bin/perl -MString::ShellQuote -e 1”.

=== ERROR while compiling conf-perl-string-shellquote.1 ======================#
context 2.0.8 | freebsd/x86_64 | ocaml-variants.4.13.1+options | https://opam.ocaml.org#132e6b30
path /usr/home/x/.opam/4.13.1+options/.opam-switch/build/conf-perl-string-shellquote.1
command /usr/local/bin/perl -MString::ShellQuote -e 1
exit-code 2
env-file /usr/home/x/.opam/log/conf-perl-string-shellquote-25694-d2c37b.env
output-file /usr/home/x/.opam/log/conf-perl-string-shellquote-25694-d2c37b.out
output ###
Can’t locate String/ShellQuote.pm in @INC (you may need to install the String::ShellQuote module) (@INC contains: /home/x/perl5/lib/perl5/5.32.1/amd64-freebsd-thread-multi /home/x/perl5/lib/perl5/5.32.1 /home/x/perl5/lib/perl5/amd64-freebsd-thread-multi /home/x/perl5/lib/perl5 /usr/local/lib/perl5/site_perl/mach/5.32 /usr/local/lib/perl5/site_perl /usr/local/lib/perl5/5.32/mach /usr/local/lib[…]
BEGIN failed–compilation aborted.
=== ERROR while compiling conf-perl-ipc-system-simple.1 ======================#
context 2.0.8 | freebsd/x86_64 | ocaml-variants.4.13.1+options | https://opam.ocaml.org#132e6b30
path /usr/home/x/.opam/4.13.1+options/.opam-switch/build/conf-perl-ipc-system-simple.1
command /usr/local/bin/perl -MIPC::System::Simple -e 1
exit-code 2
env-file /usr/home/x/.opam/log/conf-perl-ipc-system-simple-25694-05296d.env
output-file /usr/home/x/.opam/log/conf-perl-ipc-system-simple-25694-05296d.out
output ###
Can’t locate IPC/System/Simple.pm in @INC (you may need to install the IPC::System::Simple module) (@INC contains: /home/x/perl5/lib/perl5/5.32.1/amd64-freebsd-thread-multi /home/x/perl5/lib/perl5/5.32.1 /home/x/perl5/lib/perl5/amd64-freebsd-thread-multi /home/x/perl5/lib/perl5 /usr/local/lib/perl5/site_perl/mach/5.32 /usr/local/lib/perl5/site_perl /usr/local/lib/perl5/5.32/mach /usr/local/li[…]
BEGIN failed–compilation aborted.

<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
┌─ The following actions failed
│ λ build conf-perl-ipc-system-simple 1
│ λ build conf-perl-string-shellquote 1
└─
╶─ No changes have been performed

If i’m correct i must install “devel/p5-IPC-System-Simple”
What a strange dependency on a different language ie perl and ipc ? Not yet sockets ?

required by camlp5. Apparently freebsd is a recently-supported opam platform, so these support libraries haven’t been updated yet.

I have definitely thought about it but haven’t made an attempt. I don’t think it would be that difficult but that is usually how I feel before I’ve actually made an effort to get something done :wink:.

1 Like

No pasaran part2.
Installed-perl-ipc on freebsd then,
opam install camlp5
OK

opam install sexp_pretty
The following actions will be performed:
∗ install sexp_pretty v0.14.0
<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[sexp_pretty.v0.14.0] downloaded from cache at https://opam.ocaml.org/cache
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
∗ installed sexp_pretty.v0.14.0
Done.
OK.

git clone p5scm
gmake
dune build --profile release @install @runtest
make src/lib/exparser.{ml,mli},src/lib/pa_scheme.ml,src/lib/pconfig.ml,src/lib/pr_dump.ml,src/lib/pr_o.ml (exit 1)
(cd _build/default/src/lib/camlp5 && /usr/bin/make)
cppo pa_schemer.cppo.ml -o pa_schemer.ml
camlp5 pa_r.cmo pa_rp.cmo pa_extend.cmo q_MLast.cmo pr_o.cmo pa_schemer.ml -o …/pa_scheme.ml
cppo pr_o.cppo.ml -o pr_o.ml
camlp5 pa_r.cmo pa_rp.cmo pa_macro.cmo q_MLast.cmo pa_extfun.cmo pa_extprint.cmo pa_pprintf.cmo pr_o.cmo pr_o.ml -o …/pr_o.ml
cppo pr_dump.cppo.ml -o pr_dump.ml
camlp5 pa_r.cmo pr_o.cmo pr_dump.ml -o …/pr_dump.ml
camlp5 pa_r.cmo q_MLast.cmo pr_o.cmo exparser.ml -o …/exparser.ml
camlp5 pa_r.cmo q_MLast.cmo pr_o.cmo exparser.mli -o …/exparser.mli
cp ./ocaml_stuff//utils/pconfig.ml …/pconfig.ml
cp: ./ocaml_stuff//utils/pconfig.ml: No such file or directory
*** Error code 1
Stop.
make[1]: stopped in /usr/home/x/p5scm/p5scm/_build/default/src/lib/camlp5
gmake: *** [Makefile:6: build] Error 1

The following:

cp ./ocaml_stuff//utils/pconfig.ml …/pconfig.ml

on my system is:

cp ./ocaml_stuff/4.13.X/utils/pconfig.ml ../pconfig.ml

as you are using OCaml 4.13.1 this should be the same for you. I’m using a mix of dune and Makefile as I don’t know how to do this fully with dune for the camlp5 parts. The culprit is very likely VERSION0 at the top of this Makefile.

I can image many configurations are possible.
Currenlty trying linux gentoo.

opam install camlp5
[NOTE] Package camlp5 is already installed (current version is 8.00.02).
OK

opam install p5scm
[NOTE] Package p5scm is already installed (current version is 0.1.0).
OK

man p5scm
No manual entry for p5scm

/home/x/.opam/default/bin/p5scm -?
Fatal error: exception Sys_error("-?: No such file or directory")

/home/x/.opam/default/bin/p5scm -h
Fatal error: exception Sys_error("-h: No such file or directory")

cat file1.scm
(define _
(Printf.printf “Hello world”))

/home/x/.opam/default/bin/p5scm ./file1.scm
Output :
“A@K�A@Q@��A@K�A@Q@@@��@���+Hello world��A@Y�▒A@f@@��A@Y�A@f@@@@��A@J� A@g@@@@��"A@H�#A@g@@��%A@@�&A@h@@”

Looks like it installed correctly on Gentoo. The wonky output is OCaml bytecode straight to stdout. Clearly a man page and some command line options would be a nice touch but in my defence this is a 0.1.0. Try p5scm-utop and play around in the REPL. For sure (Printf.printf "Hello world") will work while assigning to _ won’t.

When i write output to a file:
./p5scm file1.scm > test

And try to interprete the produced bytecode, i get,
ocamlrun test
the file ‘test’ has not the right magic number: expected Caml1999X030, got

p5scm-utop works.
[ Now we just need a schemer which produces assembly code (feature request) ]

Sorry, I misspoke as it doesn’t emit OCaml bytecode but the parsetree. Put the following in file1.scm:

(Printf.printf "Howdi\n")

Now do either of the following:

p5scm file1.scm > test.ml
ocamlc test.ml

or

p5scm file1.scm > test.ml
ocamlopt test.ml

then run

./a.out

When i put the output of p5scm to a .ml file. This .ml output compiles with ocamlopt to a direct executable binary. That works.

PS : It would be good if there would be a separate file extension for the not human readable output of a parsetree.

.mlp ?

Not for me to decide. This is how ppx extensions work as well.

Compilation and running succeeded on Freebsd 13.0.
I had to take 2 small manual actions.

Putting a softlinks in the root git directory i.e.
ocaml_stuff → ./src/lib/camlp5/ocaml_stuff/

Putting a softlink in the ocaml_stuff directory i.e.
utils → ./4.13.X/utils/

Then gmake succeeded.

I’ve written as small counter in p5scm. The syntax must get used to but it’s good readable code.
As editor i used drracket

(define (_)
  (begin
    (Printf.printf "%s" "Starting\n")
    (let (
          (t (ref 1))
          )
      (while (< (!t) 5)
             (begin
               (Printf.printf "%d\n" (!t))
               (Printf.printf "%d\n" (!t))
               (:= t.val (+ (!t) 1))
               )
             )
      )
    (Printf.printf "%s" "Done\n")))

I will try p5scm to write small application which uses owl to plot data from a time-series postgresql database.
Can you inform me if it is possible to do type annotation and/or use objects ?

What is good is that p5scm has little syntactic rules. Meaning, it’s easy to write something which produces p5scm code.
[I.e. hierarchy of additional levels of abstraction]

1 Like

I don’t have a FreeBSD system to test. Try the following:

echo "4.13.1" | head -c 6 | sed 's/\(.*\)[0-9]/\1X/'

My guess is that it will return an empty string and not 4.13.X and hence the problem.

I didn’t design the scheme-like syntax in pa_schemer.ml that is in camlp5. Just added a simple menhir parser and hooked it up with utop. Sounds easy but it actually wasn’t so straight forward. camlp5 is pretty powerful even though not popular these days. I’d be shocked if the original author of camlp5 wasn’t thinking the same things I have when he put in the effort to make pa_schemer.ml. As for type annotations etc. this is fully OCaml so typed exactly the same way. If in the p5scm-utop repl you type (define a 1) it will tell you it is an integer.

It returns a string:
HOST:x: /home/x >echo “4.13.1” | head -c 6 | sed ‘s/(.*)[0-9]/\1X/’
4.13.X%

Note there is sed (bsd-version) & gsed (gnu-version) for freebsd.

Yes, I was aware there were differences. This however is most definitely not what I expected to see. I have no idea where the extra “%” is coming from.

The % comes from the “head function”, it appends it.
To remove it : " | awk NF=1"