Discussion:
[polyml] linking polyML modules to C
David Topham
2015-01-15 23:54:01 UTC
Permalink
After more experimenting with GUI in SML, I would like to now try calling
an SML module from a C program. That way, the GUI could be built using
traditional imperative techniques and the program logic could be written in
SML. I see how to call a C function from SML, but and not so clear on how
to call an SML function from a C program. I want to build code using polyc
and then link with a C main program, but could anyone show me a simple
example of calling that function and getting its return value? for
example, I have defined:

fun sum i n f = if i > n
then 0.0
else f i + sum (i+1) n f ;
fun int2real x = real x ;

in linkToC.sml

and

#include <iostream>
#include <fstream>
std::ofstream ofs;
int main()
{
std::cout << sum(1,10,int2real) << std::endl;
ofs.open("table.dat");
for(int i = 0; i < 20; i++)
ofs << i << '\t' << sum(1,i,int2real) << std::endl;
}

in linkToC.cpp

Looking in the polyc script, I thought adding the -c option might allow me
to build
the object code which I could then link to the sml functions, but it
complains about
not having a main.

Could someone point me in the right direction? Thanks, Dave
David, Thank you so much! I really appreciate your help with this. Your
sample below builds fine with polyc on my system (PolyML 5.5.2). I am using
a minimal Linux distribution named TinyCore (
http://distro.ibiblio.org/tinycorelinux/) which comes with OpenMotif
2.3.3 It runs in a virtual machine within another computer only taking up
a few hundred MBs!
I am going to use it to help my students explore Discrete Math next
http://cs.wheaton.edu/~tvandrun/dmfp/).
http://www.lemma-one.com/ProofPower/index/
...however it was built on PolyML 4 and has not yet been ported to the
newer version (e.g. depends on PolyML.commit which no longer seems to be
supported).
Happy Holidays to everyone in the PolyML community!
-David Topham
Re: GUI Interface (David Matthews)
I've experimented with building a stand-alone executable with Motif and
succeeded in getting it to work for me using polyc. (It required
building Poly/ML with --with-x). I took the example from
http://www.polyml.org/docs/Motif.html and wrapped it up in a function.
I did find a problem, though. It looks as though the function has to
suspend itself with something like Posix.Process.pause otherwise nothing
happens. I seem to recall that the Motif stuff is handled on a separate
thread to allow the REPL to continue to accept commands. With a
stand-alone application there isn't a REPL so without the "pause" it
terminates immediately.
David
open XWindows ;
open Motif ;
fun main() =
let
val shell =
XtAppInitialise "" "xed" "Editor" [] [XmNwidth 400, XmNheight 400] ;
val main = XmCreateMainWindow shell "main" [] ;
val bar = XmCreateMenuBar main "bar" [] ;
val fileMenu = XmCreateCascadeButton bar "file" [XmNlabelString "File"] ;
val editMenu = XmCreateCascadeButton bar "edit" [XmNlabelString "Edit"] ;
val viewMenu = XmCreateCascadeButton bar "view" [XmNlabelString "View"] ;
val helpMenu = XmCreateCascadeButton bar "help" [XmNlabelString "Help"] ;
val command = XmCreateText main "command" [XmNeditMode
XmSINGLE_LINE_EDIT] ;
val hscroll = XmCreateScrollBar main "hscroll" [XmNorientation
XmHORIZONTAL] ;
val vscroll = XmCreateScrollBar main "vscroll" [XmNorientation
XmVERTICAL] ;
val work = XmCreateDrawingArea main "work" [] ;
in
XtManageChildren [fileMenu, editMenu, viewMenu, helpMenu] ;
XtManageChildren [bar, command, hscroll, vscroll, work] ;
XmMainWindowSetAreas main bar command hscroll vscroll work ;
XtManageChild main ;
XtRealizeWidget shell;
Posix.Process.pause()
end;
------------------------------
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
End of polyml Digest, Vol 110, Issue 12
***************************************
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
David Matthews
2015-01-18 12:41:17 UTC
Permalink
David,
This isn't possible. There's no way to build a library from SML using
Poly/ML and link it with a main program written in some other language.
It is possible to do the reverse, to load a shared library written in,
say C, and use that from ML but you need to use the CInterface (FFI)
structure.

David
Post by David Topham
After more experimenting with GUI in SML, I would like to now try calling
an SML module from a C program. That way, the GUI could be built using
traditional imperative techniques and the program logic could be written in
SML. I see how to call a C function from SML, but and not so clear on how
to call an SML function from a C program. I want to build code using polyc
and then link with a C main program, but could anyone show me a simple
example of calling that function and getting its return value? for
fun sum i n f = if i > n
then 0.0
else f i + sum (i+1) n f ;
fun int2real x = real x ;
in linkToC.sml
and
#include <iostream>
#include <fstream>
std::ofstream ofs;
int main()
{
std::cout << sum(1,10,int2real) << std::endl;
ofs.open("table.dat");
for(int i = 0; i < 20; i++)
ofs << i << '\t' << sum(1,i,int2real) << std::endl;
}
in linkToC.cpp
Looking in the polyc script, I thought adding the -c option might allow me
to build
the object code which I could then link to the sml functions, but it
complains about
not having a main.
Could someone point me in the right direction? Thanks, Dave
David, Thank you so much! I really appreciate your help with this. Your
sample below builds fine with polyc on my system (PolyML 5.5.2). I am using
a minimal Linux distribution named TinyCore (
http://distro.ibiblio.org/tinycorelinux/) which comes with OpenMotif
2.3.3 It runs in a virtual machine within another computer only taking up
a few hundred MBs!
I am going to use it to help my students explore Discrete Math next
http://cs.wheaton.edu/~tvandrun/dmfp/).
http://www.lemma-one.com/ProofPower/index/
...however it was built on PolyML 4 and has not yet been ported to the
newer version (e.g. depends on PolyML.commit which no longer seems to be
supported).
Happy Holidays to everyone in the PolyML community!
-David Topham
Re: GUI Interface (David Matthews)
I've experimented with building a stand-alone executable with Motif and
succeeded in getting it to work for me using polyc. (It required
building Poly/ML with --with-x). I took the example from
http://www.polyml.org/docs/Motif.html and wrapped it up in a function.
I did find a problem, though. It looks as though the function has to
suspend itself with something like Posix.Process.pause otherwise nothing
happens. I seem to recall that the Motif stuff is handled on a separate
thread to allow the REPL to continue to accept commands. With a
stand-alone application there isn't a REPL so without the "pause" it
terminates immediately.
David
open XWindows ;
open Motif ;
fun main() =
let
val shell =
XtAppInitialise "" "xed" "Editor" [] [XmNwidth 400, XmNheight 400] ;
val main = XmCreateMainWindow shell "main" [] ;
val bar = XmCreateMenuBar main "bar" [] ;
val fileMenu = XmCreateCascadeButton bar "file" [XmNlabelString "File"] ;
val editMenu = XmCreateCascadeButton bar "edit" [XmNlabelString "Edit"] ;
val viewMenu = XmCreateCascadeButton bar "view" [XmNlabelString "View"] ;
val helpMenu = XmCreateCascadeButton bar "help" [XmNlabelString "Help"] ;
val command = XmCreateText main "command" [XmNeditMode
XmSINGLE_LINE_EDIT] ;
val hscroll = XmCreateScrollBar main "hscroll" [XmNorientation
XmHORIZONTAL] ;
val vscroll = XmCreateScrollBar main "vscroll" [XmNorientation
XmVERTICAL] ;
val work = XmCreateDrawingArea main "work" [] ;
in
XtManageChildren [fileMenu, editMenu, viewMenu, helpMenu] ;
XtManageChildren [bar, command, hscroll, vscroll, work] ;
XmMainWindowSetAreas main bar command hscroll vscroll work ;
XtManageChild main ;
XtRealizeWidget shell;
Posix.Process.pause()
end;
------------------------------
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
End of polyml Digest, Vol 110, Issue 12
***************************************
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
David Topham
2015-01-19 04:34:34 UTC
Permalink
Thanks David for your response.

While searching I found this comment you made earlier:

"The foreign-function interface allows for call-back functions so there is
the mechanism to produce a C function that when called calls an ML
function."

in
http://stackoverflow.com/questions/17580386/shared-libraries-in-poly-ml

Doesn't this indicate a mechanism that allows an SML function to be called
from C?

I accept your answer though, and wonder then if continuing exploration of
toolkit wrappers such as the Motif interface is the best bet for adding a
GUI to ML?

I wonder how projects such as Isabelle and ProofPower integrate a GUI?
If anyone has suggestions I would appreciate it. My goal is not an
elaborate interface--just simple I/O with labels, images, buttons, and text
input to explore functional approaches.

-Dave
Send polyml mailing list submissions to
To subscribe or unsubscribe via the World Wide Web, visit
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
or, via email, send a message with subject or body 'help' to
You can reach the person managing the list at
When replying, please edit your Subject line so it is more specific
than "Re: Contents of polyml digest..."
1. linking polyML modules to C (David Topham)
----------------------------------------------------------------------
Message: 1
Date: Thu, 15 Jan 2015 15:54:01 -0800
Subject: [polyml] linking polyML modules to C
<
Content-Type: text/plain; charset="utf-8"
After more experimenting with GUI in SML, I would like to now try calling
an SML module from a C program. That way, the GUI could be built using
traditional imperative techniques and the program logic could be written in
SML. I see how to call a C function from SML, but and not so clear on how
to call an SML function from a C program. I want to build code using polyc
and then link with a C main program, but could anyone show me a simple
example of calling that function and getting its return value? for
fun sum i n f = if i > n
then 0.0
else f i + sum (i+1) n f ;
fun int2real x = real x ;
in linkToC.sml
and
#include <iostream>
#include <fstream>
std::ofstream ofs;
int main()
{
std::cout << sum(1,10,int2real) << std::endl;
ofs.open("table.dat");
for(int i = 0; i < 20; i++)
ofs << i << '\t' << sum(1,i,int2real) << std::endl;
}
in linkToC.cpp
Looking in the polyc script, I thought adding the -c option might allow me
to build
the object code which I could then link to the sml functions, but it
complains about
not having a main.
Could someone point me in the right direction? Thanks, Dave
David, Thank you so much! I really appreciate your help with this. Your
sample below builds fine with polyc on my system (PolyML 5.5.2). I am
using
a minimal Linux distribution named TinyCore (
http://distro.ibiblio.org/tinycorelinux/) which comes with OpenMotif
2.3.3 It runs in a virtual machine within another computer only taking
up
a few hundred MBs!
I am going to use it to help my students explore Discrete Math next
http://cs.wheaton.edu/~tvandrun/dmfp/).
http://www.lemma-one.com/ProofPower/index/
...however it was built on PolyML 4 and has not yet been ported to the
newer version (e.g. depends on PolyML.commit which no longer seems to be
supported).
Happy Holidays to everyone in the PolyML community!
-David Topham
Re: GUI Interface (David Matthews)
I've experimented with building a stand-alone executable with Motif and
succeeded in getting it to work for me using polyc. (It required
building Poly/ML with --with-x). I took the example from
http://www.polyml.org/docs/Motif.html and wrapped it up in a function.
I did find a problem, though. It looks as though the function has to
suspend itself with something like Posix.Process.pause otherwise nothing
happens. I seem to recall that the Motif stuff is handled on a separate
thread to allow the REPL to continue to accept commands. With a
stand-alone application there isn't a REPL so without the "pause" it
terminates immediately.
David
open XWindows ;
open Motif ;
fun main() =
let
val shell =
XtAppInitialise "" "xed" "Editor" [] [XmNwidth 400, XmNheight 400]
;
val main = XmCreateMainWindow shell "main" [] ;
val bar = XmCreateMenuBar main "bar" [] ;
val fileMenu = XmCreateCascadeButton bar "file" [XmNlabelString "File"]
;
val editMenu = XmCreateCascadeButton bar "edit" [XmNlabelString "Edit"]
;
val viewMenu = XmCreateCascadeButton bar "view" [XmNlabelString "View"]
;
val helpMenu = XmCreateCascadeButton bar "help" [XmNlabelString "Help"]
;
val command = XmCreateText main "command" [XmNeditMode
XmSINGLE_LINE_EDIT] ;
val hscroll = XmCreateScrollBar main "hscroll" [XmNorientation
XmHORIZONTAL] ;
val vscroll = XmCreateScrollBar main "vscroll" [XmNorientation
XmVERTICAL] ;
val work = XmCreateDrawingArea main "work" [] ;
in
XtManageChildren [fileMenu, editMenu, viewMenu, helpMenu] ;
XtManageChildren [bar, command, hscroll, vscroll, work] ;
XmMainWindowSetAreas main bar command hscroll vscroll work ;
XtManageChild main ;
XtRealizeWidget shell;
Posix.Process.pause()
end;
------------------------------
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
End of polyml Digest, Vol 110, Issue 12
***************************************
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <
http://lists.inf.ed.ac.uk/pipermail/polyml/attachments/20150115/62419cfc/attachment-0001.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linkToC.cpp
Type: text/x-c++src
Size: 234 bytes
Desc: not available
URL: <
http://lists.inf.ed.ac.uk/pipermail/polyml/attachments/20150115/62419cfc/attachment-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linkToC.sml
Type: application/octet-stream
Size: 164 bytes
Desc: not available
URL: <
http://lists.inf.ed.ac.uk/pipermail/polyml/attachments/20150115/62419cfc/attachment-0001.obj
------------------------------
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
End of polyml Digest, Vol 111, Issue 3
**************************************
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
Gergely Buday
2015-01-19 08:48:26 UTC
Permalink
"The foreign-function interface allows for call-back functions so there is the mechanism to produce a C function that when called calls an ML function."
in
http://stackoverflow.com/questions/17580386/shared-libraries-in-poly-ml
Doesn't this indicate a mechanism that allows an SML function to be called from C?
It is possible with MLton:

http://mlton.org/CallingFromCToSML

with a caveat:

"Unfortunately, MLton’s support for exporting ML functions to C only allows one
instance of the function to exist. Thus, we have to keep an ML-side
registry of windows and their callback functions, which is used to
multiplex the the single instance of the callback."

http://sml3d.cs.uchicago.edu/papers/ml14-sml3d/paper.pdf

This paper is worth reading for its discussion of interfacing OpenGL as well.

- Gergely
David Matthews
2015-01-19 12:19:12 UTC
Permalink
Post by David Topham
Thanks David for your response.
"The foreign-function interface allows for call-back functions so there is
the mechanism to produce a C function that when called calls an ML
function."
in
http://stackoverflow.com/questions/17580386/shared-libraries-in-poly-ml
Doesn't this indicate a mechanism that allows an SML function to be called
from C?
Yes, but the "main program" still has to be in ML. You can call C
library functions and pass an ML function as an argument.

Actually, I did wonder whether this could be used as a way of exporting
ML functions to create a library that could be called from a C main
program and came to the conclusion that it was going to be too
complicated. Poly/ML uses libffi to interface with C. libffi can build
closures that wrap around ML functions so that these can be passed into
C. The format of the closure it constructs differs markedly depending
on the particular architecture since different architectures have
different calling conventions for C. The closure is a data structure
with pointers in it. Exporting it would require turning the pointers
into relocations that the linker/loader will understand. libffi simply
doesn't provide that information. It's there by implication in the
source code but not explicitly.

David
Phil Clayton
2015-01-21 20:20:06 UTC
Permalink
Post by David Matthews
Post by David Topham
Thanks David for your response.
"The foreign-function interface allows for call-back functions so there is
the mechanism to produce a C function that when called calls an ML
function."
in
http://stackoverflow.com/questions/17580386/shared-libraries-in-poly-ml
Doesn't this indicate a mechanism that allows an SML function to be called
from C?
Yes, but the "main program" still has to be in ML. You can call C
library functions and pass an ML function as an argument.
Or the ML functions can be passed via global variables that are
initialized from the ML side - see attached example. That may be easier
if there are a large number of ML functions.
Post by David Matthews
Actually, I did wonder whether this could be used as a way of exporting
ML functions to create a library that could be called from a C main
program and came to the conclusion that it was going to be too
complicated. Poly/ML uses libffi to interface with C. libffi can build
closures that wrap around ML functions so that these can be passed into
C. The format of the closure it constructs differs markedly depending
on the particular architecture since different architectures have
different calling conventions for C. The closure is a data structure
with pointers in it. Exporting it would require turning the pointers
into relocations that the linker/loader will understand. libffi simply
doesn't provide that information. It's there by implication in the
source code but not explicitly.
David
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
David Topham
2015-01-25 06:47:35 UTC
Permalink
I wanted to follow through on this to expand the GUI to receive input, so
this is the result (here and attached). The tgz file has the sml and script
to build them as well.
-Dave

#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include <Xm/TextF.h>
#include <Xm/PushB.h>
#include <stdlib.h>
#include <ctype.h>

double (*sml_hypot) (double x, double y);

static void EnterCallback ( Widget w, XtPointer clientData, XtPointer
callData);

Widget sideA, sideB, sideC;

void c_main (void)
{
Widget shell, rowcol, button;
XtAppContext app;

int argc = 1; char* argv[] = {"PolyML GUI" };
shell = XtAppInitialize ( &app, "Memo", NULL, 0,
&argc, argv, NULL, NULL, 0 );

rowcol = XtCreateManagedWidget ("rowcol", xmRowColumnWidgetClass,
shell, NULL, 0);

XmString xmstr;
xmstr = XmStringCreateLtoR ( "Right Triangle", XmFONTLIST_DEFAULT_TAG );
XtVaCreateManagedWidget ( "message", xmLabelWidgetClass, rowcol,
XmNlabelString, xmstr, NULL );
XmStringFree ( xmstr );

sideA = XmCreateTextField ( rowcol, "input", NULL, 0 );
XtManageChild ( sideA );
sideB = XmCreateTextField ( rowcol, "input", NULL, 0 );
XtManageChild ( sideB );

button = XtCreateManagedWidget("Calculate Hypontenuse",
xmPushButtonWidgetClass, rowcol, NULL, 0 );
XtAddCallback ( button, XmNactivateCallback, EnterCallback, NULL);

sideC = XmCreateTextField ( rowcol, "input", NULL, 0 );
XtManageChild ( sideC );

XtRealizeWidget ( shell );
XtAppMainLoop ( app );

return;
}
static void EnterCallback ( Widget w, XtPointer clientData, XtPointer
callData )
{
double a, b;
printf ( "text entered = %s\n", XmTextFieldGetString ( sideA ) );
printf ( "text entered = %s\n", XmTextFieldGetString ( sideB ) );
a = atof(XmTextFieldGetString ( sideA ));
b = atof(XmTextFieldGetString ( sideB ));
double c;
c = sml_hypot (a, b); /* call back to SML! */
printf("c = %.6f\n", c);
char msg[256];
sprintf(msg,"%.1f", c);
XmTextFieldSetString(sideC,msg);
}
Wonderful! Thank you so much for posting that Phil!
I was not able to build the code using the Makefile because my system
does not have libpolyml.so;
however, the commands within the Makefile did work, so perhaps that file
is not needed?
I put them within the attached tgz file in a shell script.
gcc -fPIC -g -Wall -c testlib.c -o testlib.o
gcc -shared -Wl,-soname,testlib.so.1 -o testlib.so.1 testlib.o
polyc call_c_test_10.sml
LD_LIBRARY_PATH=. ./a.out
and this runs successfully displaying the output in an X Window!
I think this is a viable approach to integrating PolyML with a GUI or at
least graphics output but of course will require lots of experimenting...I
wish I had tons of time, but will only be able to try things
once-in-a-while now that a new semester has begun.
(but it is also in the attached tgz file if you want to try it)
#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <stdlib.h>
double (*sml_hypot) (double x, double y);
void c_main (void)
{
double a, b, c;
a = 3.0;
b = 4.0;
printf("a = %.6f\n", a);
printf("b = %.6f\n", b);
c = sml_hypot (a, b); /* call back to SML! */
printf("c = %.6f\n", c);
fflush(stdout);
char msg[256];
sprintf(msg,"c = %.6f\n", c);
Widget shell;
XtAppContext app;
XmString xmstr;
int argc = 1;
char* argv[] = {"polygui" };
shell = XtAppInitialize ( &app, "Memo", NULL, 0,
&argc, argv, NULL, NULL, 0 );
xmstr = XmStringCreateLtoR ( msg, XmFONTLIST_DEFAULT_TAG );
XtVaCreateManagedWidget ( "message",
xmLabelWidgetClass, shell,
XmNlabelString, xmstr,
NULL );
XmStringFree ( xmstr );
XtRealizeWidget ( shell );
XtAppMainLoop ( app );
return;
}
Send polyml mailing list submissions to
To subscribe or unsubscribe via the World Wide Web, visit
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
or, via email, send a message with subject or body 'help' to
You can reach the person managing the list at
When replying, please edit your Subject line so it is more specific
than "Re: Contents of polyml digest..."
1. Re: linking polyML modules to C (Phil Clayton)
----------------------------------------------------------------------
Message: 1
Date: Wed, 21 Jan 2015 20:20:06 +0000
Subject: Re: [polyml] linking polyML modules to C
Content-Type: text/plain; charset="iso-8859-1"; Format="flowed"
Post by David Matthews
Post by David Topham
Thanks David for your response.
"The foreign-function interface allows for call-back functions so
there is
the mechanism to produce a C function that when called calls an ML
function."
in
http://stackoverflow.com/questions/17580386/shared-libraries-in-poly-ml
Post by David Matthews
Post by David Topham
Doesn't this indicate a mechanism that allows an SML function to be
called
from C?
Yes, but the "main program" still has to be in ML. You can call C
library functions and pass an ML function as an argument.
Or the ML functions can be passed via global variables that are
initialized from the ML side - see attached example. That may be easier
if there are a large number of ML functions.
Post by David Matthews
Actually, I did wonder whether this could be used as a way of exporting
ML functions to create a library that could be called from a C main
program and came to the conclusion that it was going to be too
complicated. Poly/ML uses libffi to interface with C. libffi can
build
Post by David Matthews
closures that wrap around ML functions so that these can be passed into
C. The format of the closure it constructs differs markedly depending
on the particular architecture since different architectures have
different calling conventions for C. The closure is a data structure
with pointers in it. Exporting it would require turning the pointers
into relocations that the linker/loader will understand. libffi simply
doesn't provide that information. It's there by implication in the
source code but not explicitly.
David
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
-------------- next part --------------
A non-text attachment was scrubbed...
Name: call_c_test_10.tar.gz
Type: application/x-gzip
Size: 1438 bytes
Desc: not available
URL: <
http://lists.inf.ed.ac.uk/pipermail/polyml/attachments/20150121/edcb7e81/attachment-0001.gz
------------------------------
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
End of polyml Digest, Vol 111, Issue 7
**************************************
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
David Topham
2018-11-09 05:29:02 UTC
Permalink
I am trying to use the debugger in PolyML but always get errors. Here is
my code:

PolyML.Compiler.debug := true;
open PolyML.Debug;
fun member(x,[]) = false
| member(x,(y::ys)) = if x = y then true else member(x,(ys));
member(2,[2,3,4]); (* expect true *)
member(5,[2,3,4]); (* expect false *)
fun subset([],s) = true
| subset((x::xs),s) = member(x,s) andalso subset(xs,s);
fun equals(s1,s2) = subset(s1,s2) andalso subset(s2,s1);
breakIn "subset";

subset([],[1,2,3]); (* expect true *)
subset([2],[1,2,3]); (* expect true *)

It does break at the debug prompt, but when typing

dump();

it crashes with: Function subset:Exception- Cast "toAddress" raised

Do you have any suggestions?

I am using Debian 9 64-bit and installed using apt-get

"polyml is already the newest version (5.6-8)"

-Dave
Post by David Topham
After more experimenting with GUI in SML, I would like to now try calling
an SML module from a C program. That way, the GUI could be built using
traditional imperative techniques and the program logic could be written in
SML. I see how to call a C function from SML, but and not so clear on how
to call an SML function from a C program. I want to build code using polyc
and then link with a C main program, but could anyone show me a simple
example of calling that function and getting its return value? for
fun sum i n f = if i > n
then 0.0
else f i + sum (i+1) n f ;
fun int2real x = real x ;
in linkToC.sml
and
#include <iostream>
#include <fstream>
std::ofstream ofs;
int main()
{
std::cout << sum(1,10,int2real) << std::endl;
ofs.open("table.dat");
for(int i = 0; i < 20; i++)
ofs << i << '\t' << sum(1,i,int2real) << std::endl;
}
in linkToC.cpp
Looking in the polyc script, I thought adding the -c option might allow me
to build
the object code which I could then link to the sml functions, but it
complains about
not having a main.
Could someone point me in the right direction? Thanks, Dave
David, Thank you so much! I really appreciate your help with this. Your
sample below builds fine with polyc on my system (PolyML 5.5.2). I am using
a minimal Linux distribution named TinyCore (
http://distro.ibiblio.org/tinycorelinux/) which comes with OpenMotif
2.3.3 It runs in a virtual machine within another computer only taking up
a few hundred MBs!
I am going to use it to help my students explore Discrete Math next
http://cs.wheaton.edu/~tvandrun/dmfp/).
http://www.lemma-one.com/ProofPower/index/
...however it was built on PolyML 4 and has not yet been ported to the
newer version (e.g. depends on PolyML.commit which no longer seems to be
supported).
Happy Holidays to everyone in the PolyML community!
-David Topham
Re: GUI Interface (David Matthews)
I've experimented with building a stand-alone executable with Motif and
succeeded in getting it to work for me using polyc. (It required
building Poly/ML with --with-x). I took the example from
http://www.polyml.org/docs/Motif.html and wrapped it up in a function.
I did find a problem, though. It looks as though the function has to
suspend itself with something like Posix.Process.pause otherwise nothing
happens. I seem to recall that the Motif stuff is handled on a separate
thread to allow the REPL to continue to accept commands. With a
stand-alone application there isn't a REPL so without the "pause" it
terminates immediately.
David
open XWindows ;
open Motif ;
fun main() =
let
val shell =
XtAppInitialise "" "xed" "Editor" [] [XmNwidth 400, XmNheight 400] ;
val main = XmCreateMainWindow shell "main" [] ;
val bar = XmCreateMenuBar main "bar" [] ;
val fileMenu = XmCreateCascadeButton bar "file" [XmNlabelString "File"] ;
val editMenu = XmCreateCascadeButton bar "edit" [XmNlabelString "Edit"] ;
val viewMenu = XmCreateCascadeButton bar "view" [XmNlabelString "View"] ;
val helpMenu = XmCreateCascadeButton bar "help" [XmNlabelString "Help"] ;
val command = XmCreateText main "command" [XmNeditMode
XmSINGLE_LINE_EDIT] ;
val hscroll = XmCreateScrollBar main "hscroll" [XmNorientation
XmHORIZONTAL] ;
val vscroll = XmCreateScrollBar main "vscroll" [XmNorientation
XmVERTICAL] ;
val work = XmCreateDrawingArea main "work" [] ;
in
XtManageChildren [fileMenu, editMenu, viewMenu, helpMenu] ;
XtManageChildren [bar, command, hscroll, vscroll, work] ;
XmMainWindowSetAreas main bar command hscroll vscroll work ;
XtManageChild main ;
XtRealizeWidget shell;
Posix.Process.pause()
end;
------------------------------
_______________________________________________
polyml mailing list
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
End of polyml Digest, Vol 110, Issue 12
***************************************
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
David Matthews
2018-11-09 13:13:17 UTC
Permalink
Dave,
It seems to be a bug with printing the value of a polymorphic equality
type variable. "s" has type ''a and that upsets the debugger. It works
either if there is a type constraint to force the type of "s" to be int
list or if "member" is changed so that the equality function is passed
as an argument and the functions are fully polymorphic. I need to find
out why equality types cause problems.

David
Post by David Topham
I am trying to use the debugger in PolyML but always get errors. Here is
PolyML.Compiler.debug := true;
open PolyML.Debug;
fun member(x,[]) = false
| member(x,(y::ys)) = if x = y then true else member(x,(ys));
member(2,[2,3,4]); (* expect true *)
member(5,[2,3,4]); (* expect false *)
fun subset([],s) = true
| subset((x::xs),s) = member(x,s) andalso subset(xs,s);
fun equals(s1,s2) = subset(s1,s2) andalso subset(s2,s1);
breakIn "subset";
subset([],[1,2,3]); (* expect true *)
subset([2],[1,2,3]); (* expect true *)
It does break at the debug prompt, but when typing
dump();
it crashes with: Function subset:Exception- Cast "toAddress" raised
Do you have any suggestions?
I am using Debian 9 64-bit and installed using apt-get
"polyml is already the newest version (5.6-8)"
-Dave
Loading...