Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ANN: Logtalk 3.6.0 released

45 views
Skip to first unread message

Paulo Moura

unread,
Jun 13, 2016, 9:26:21 AM6/13/16
to
Hi,

Logtalk 3.6.0 is now available for downloading at:

http://logtalk.org/

This release highlight is a new threaded engines API, sponsored by Kyndi Inc. For a gentle introduction to threaded engines, see:

http://logtalk.org/manuals/userman/threads.html#threads_engines

Threaded engines can be used to implement e.g. fluents, lazy meta-predicates, interactors, and agents. Several examples are included:

https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/engines

Also included are updates, improvements, and fixes for the compiler, adapter files, tools, examples, tests, and text editor support. For details and a complete list of changes, please consult the release notes at:

https://github.com/LogtalkDotOrg/logtalk3/blob/master/RELEASE_NOTES.md

Happy logtalking!

Paulo

Jan Burse

unread,
Jun 15, 2016, 4:27:27 PM6/15/16
to
Hi,

Does the new Logtalk release obsolete:
http://logtalk.org/plstd/threads.pdf

In the sense that you do not anymore support the 13211-5
suggested API, and that you go with a new API that you
also will support in the future.

Or is there a certain co-existence?

Bye

Paulo Moura schrieb:

Paulo Moura

unread,
Jun 16, 2016, 7:25:46 AM6/16/16
to
On Wednesday, June 15, 2016 at 9:27:27 PM UTC+1, Jan Burse wrote:
> Hi,
>
> Does the new Logtalk release obsolete:
> http://logtalk.org/plstd/threads.pdf

No. Both new and former thread APIs co-exist and are fully supported. The new threaded engines API provides different, non-overlapping, functionality.

Paulo Moura

unread,
Jun 19, 2016, 5:13:32 PM6/19/16
to
Logtalk 3.6.1, released today, provides the final threaded engines API. It renames some of the engine predicates for facilitating porting code between coroutining and threaded engine APIs and adds a new predicate for retrieving engine answers in reified form.

Enjoy,
Paulo

Jan Burse

unread,
Jul 5, 2016, 11:27:10 AM7/5/16
to
Actually I don't like the ISO/IEC DTR 13211{5:2007 very much.
It is not really based on:
- Abstract Datatypes that might happen to use Monitors
(Most annoying)
- In case there are Datatypes, we always need some explizit destroy
(Less annoying)

As a result, since there are not really separate data types
in the proposal in carefully showing inheritance or union types,
we seen monsters like:

3.2.7.4 Examples
thread_send_message(t, exit).

3.6 Thread and message queue communication
thread_send_message(queue2, father(antonio))

3.6.1.2 Template and modes
thread send message(+queue or alias, @term)

So somehow in the evolution of this API, people where first
thinking of only sending messages to threads, like in the
Hewitt Actor model. (3.2.7.4 Examples)

Then it occured that no, we can also have queues separately
in existence, and communicate with them. ( 3.6 Thread and
message queue communication).

As a result the predicate has:
- An awful name, its called thread_send_message/2,
wouldn't be queue_send/2 be a better name?

- Incomplete documentation, 3.6.1.2 Template and modes
mentions only queue as argument and not thread as argument.
thread_send_message(+queue or alias, @term)

SWI-Prolog is more precise here:
thread_send_message(+QueueOrThreadId, +Term)
http://www.swi-prolog.org/pldoc/man?predicate=thread_send_message/2

- We always need alias/1 options, and all the predicates
need to also accept naming of an object. this has already
started in the ISO standard for streams.

But is this needed if we could do the following with references?
?- mutex_new(M), assertz(my_table(my_alias, M)).

Etc..

I was exploring an other path recently, preparing next release
1.1.5 of Jekejeke Prolog Runtime:

Enhanced Module thread:

http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/10_docu/05_frequent/07_theories/20_system/04_thread.html

New Module lock:

http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/10_docu/05_frequent/07_theories/21_misc/03_lock.html

New Module queue:

http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/10_docu/05_frequent/07_theories/21_misc/04_queue.html

Well, one cannot send a message to a thread in the
above API, still exploring whether this is really needed.(*)
Here is an example of a findall implemented via threads,
that explicitly deals with queues:

threadall/3 predicate: Findall via threads

https://gist.github.com/jburse/696ab00b089e615577002b7854e3ca7f#file-all-p
(No error handling yet implemented)

Bye

(*)
In the Go programming language (Golang) from Google there are
also first Go routines, i.e. the go statement, and then later
channels as first class objects.

Maybe could learn from Golang, and enhance the module "queue"
into a module "channel", adding things like closing a channel,
or selecting from multiple channels.

http://guzalexander.com/2013/12/06/golang-channels-tutorial.html

Jan Burse schrieb:

j4n bur53

unread,
Jul 5, 2016, 4:59:21 PM7/5/16
to
There is a certain dilemma involved.

If we say a thread has always queue, we are probably in
the Haskell domain of monads. We can solve the following
problem:

Pipes.Concurrent.Tutorial
https://hackage.haskell.org/package/pipes-concurrency-2.0.6/docs/Pipes-Concurrent-Tutorial.html

We might or might not need additional threads. Depending
whether we can do something along the following in one
thread:

(Job_i toOutput mailbox)

In the Golang scenario Job_i is already started as a thread
somewhere in the universe and all we know is the channel.
And the Golang select would allow us the mailbox merging.

Probably need some callback architecture for the channels
itself, so as to do the merging without starting additional
threads that listen on the channels and move stuff to
the mailbox.

Hm

How do that?

Bye

Haskell avoids it, Golang uses select, recuring problem:
http://camel.apache.org/polling-consumer.html
Also in Unix there is select and poll.

j4n bur53

unread,
Jul 5, 2016, 5:04:43 PM7/5/16
to
j4n bur53 schrieb:
> How do that?

BTW: Golang can do the select both for gets and sends!
In sends it can notice whether buffers are full, and do
work somewhere else. Very clever!

https://gobyexample.com/non-blocking-channel-operations

Bye

j4n bur53

unread,
Jul 5, 2016, 5:15:30 PM7/5/16
to
j4n bur53 schrieb:
> There is a certain dilemma involved.

Prologers should know this dilemma.
Its also already seen in ordinary Prolog execution.
There is the following ambiguity:

?- p(X, Y).

Do we call a goal p/2? (analog to thread)
Or do we solve for instantiations of X and Y?
(analog to channel)


Attribute variables etc.. show that a lot
can be done with the channel view of
Prolog execution, i.e. CLP(FD) etc..

Bye

Jan Burse

unread,
Jul 8, 2016, 6:02:47 AM7/8/16
to
For example we might challenge whether we need
a thread_join/1, which gives us the burden of having
a thread handle. Respectively all (sic!) thread handles
in the master that waits for its slaves.

And even some strange programming practice that
calls thread_join/1 for all the thread handles
one by one.

Under the channels view point, this might not be a
characteristic that is desired that a group of
work has been completed. Here is an experiment in
read write locks for wait groups:

Using read write pair as a wait group. (Jekejeke)
https://plus.google.com/+JekejekeCh/posts/1h35NhFNuUY

Jan Burse schrieb:

Jan Burse

unread,
Jul 8, 2016, 8:12:16 AM7/8/16
to
Still there is some happy path syndrom involved.
When we adopt the Go programming language approach
of using a wait group semaphore instead of thread_join/1
we are still left with the following problem:

What if we want to cleanup the slaves if
the master is interrupted
(in SWI-Prolog assume we press Ctrl-C and a
in the toplevel when the master runs, we
might want to clean up all the slaves)

Here are some solutions to this problem:

1) Thread Handles
-----------------
Go with thread handles, i.e. use thread_join/1
in the first place, and when there is a cleanup
request use something along thread_kill/1.

2) Tarau's Trail
----------------
Use Tarau's Engines idea of trailung threads.
So in place where I am creating a thread as
follows:

thread_new(start_member(P, Q, N), I),

We would go asfollows:

assume_thread(start_member(P, Q, N), I),

But this is a little intransparent, when is
exactly the moment that a slave is cleaned-up
and how is the slave cleaned-up?

3) Thread Groups
----------------
This is almost the same as thread handles. We
would use some OS provided data structure to
collect the thread handles.

4) Channels Again
-----------------
Here is the Go programming language proposal:

https://blog.golang.org/pipelines

It hinges on the close() operation on a channel,
which pushes infinite null values.

!! Channels Again !!

Bye

Jan Burse schrieb:

Jan Burse

unread,
Jul 8, 2016, 8:23:03 AM7/8/16
to
Jan Burse schrieb:
> 4) Channels Again
> -----------------
> Here is the Go programming language proposal:
>
> https://blog.golang.org/pipelines
>
> It hinges on the close() operation on a channel,
> which pushes infinite null values.

But as the blog correctly observes, the <-done
message must also be understood by all the slaves,
not only the merger!


0 new messages