# When does assert fail? Running out of space?

**URL:** <https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681>\
**Category:** Help!\
**Created:** [December 31, 2019, 4:48pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681 "2019-12-31T16:48:23Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [January 2, 2020, 2:16pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/41 "2020-01-02T14:16:28Z")

</div>

take the simplest case possible and describe it in both ways – then add a pinch of non determinism to it 🙂

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 2, 2020, 2:22pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/42 "2020-01-02T14:22:49Z")

</div>

> [@EricGT](#):
>
> ![](https://global.discourse-cdn.com/free1/uploads/swiprolog/original/1X/5b04169c167b65508900a4e4781d4f2e8f48725f.jpeg) jan:
> 
> > a two-argument term such that we can pass along both the missing value and the exception.
> 
> In understanding and having used _railway-oriented programming_ in F# some of the finer concepts that need to be considered:
> 
> 1. …
> 2. … in the error part of the two part term …
> 3. … then the error part of the two part term …

This is a **critical misunderstanding** of the _expected_ monad and we should not let it linger. The idea of this monad is that **either** we have an expected value **or** data on **why** an expected value is **missing**. If we don’t have an expected value, there’s no rationale for a two part term. To be blunt, writing “both the missing value and the exception” makes no sense.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [January 2, 2020, 2:23pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/43 "2020-01-02T14:23:11Z")

</div>

> [@grossdan](#):
>
> take the simplest case possible and describe it in both ways – then add a pinch of non determinism to it 🙂

My problem is how to I translate an algebraic data type into Prolog. I visited this idea in these post ([A](https://swi-prolog.discourse.group/t/using-has-type-list-type-x-with-user-created-type-not-working-as-expected/1340), [B](https://swi-prolog.discourse.group/t/types-with-swi-prolog/1341)), but never made it past the point of getting it off the back burner.

Right now the cleanest way I see to put this into working Prolog code is to add state to the predicates with the state containing a compound term for the result, one part for the valid (happy) path and one part for the exception/error (unhappy) path.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [January 2, 2020, 2:28pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/44 "2020-01-02T14:28:11Z")

</div>

I think, perhaps this can be done by collecting and nesting Expected references in logtalk - but, one needs to also add the operators – somehow.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 2, 2020, 2:29pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/45 "2020-01-02T14:29:43Z")

</div>

> [@EricGT](#):
>
> Right now the cleanest way I see to put this into working Prolog code is to add state to the predicates with the state containing a compound term for the result, one part for the valid (happy) path and one part for the exception/error (unhappy) path.

That’s not clean. If you use the same compound term for **both** the _happy path_ part and the _something went wrong_ part, then, for any given case, one of the parts will be unbound, which means that you always have to look inside the compound term and test. Carrying around unbound arguments for the sake of representing the absence of something is not good practice.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [January 2, 2020, 2:30pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/46 "2020-01-02T14:30:32Z")

</div>

> [@pmoura](#):
>
> To be blunt, writing “both the missing value and the exception” makes no sense.

You are probably right, when I quoted the statement I was focused on the “two-argument term” and not so much the “the missing value and the exception”.

In F# the return value with _railway-oriented programming_ is a algebraic data type that is the union of the valid type and another type to represent an error or some other unexpected result. The simplest example in another language would be the [Haskell maybe monad](https://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe) but I don’t know Haskell so can’t attest that it is exactly the same.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [January 2, 2020, 2:35pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/47 "2020-01-02T14:35:00Z")

</div>

> [@pmoura](#):
>
> That’s not clean. If you use the same compound term for **both** the _happy path_ part and the _something went wrong_ part, then, for any given case, one of the parts will be unbound, which means that you always have to look inside the compound term and test. Carrying around unbound arguments for the sake of representing the absence of something is not good practice.

Yes, that sounds right, and why I note that I don’t know how to create an algebraic data type in Prolog. That is also why I am hesitant to post code trying to explain such because it might be picked up and propagated which would be even worse.

Thanks for the reply. 😃

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 2, 2020, 2:37pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/48 "2020-01-02T14:37:37Z")

</div>

> [@EricGT](#):
>
> In F# the return value with _railway-oriented programming_ is a algebraic data type that is the union of the valid type and another type to represent an error or some other unexpected result. The simplest example in another language would be the [Haskell maybe monad](https://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe) but I don’t know Haskell so can’t attest that it is exactly the same.

_Optionals_ (aka _maybe_ monad) and _expecteds_ are two **different** monads serving different scenarios. E.g. in Logtalk you have both [optionals](https://logtalk.org/library/library_index.html#optionals) and [expecteds](https://logtalk.org/library/library_index.html#expecteds) libraries.

The two blog posts that Daniel already cited should help in understanding the differences:

Optionals: [Handling optional data - Logtalk](https://logtalk.org/2019/11/27/handling-optional-data.html)  
Expecteds: [Handling missing data - Logtalk](https://logtalk.org/2019/11/21/handling-missing-data.html)

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [January 2, 2020, 2:54pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/49 "2020-01-02T14:54:18Z")

</div>

> [@pmoura](#):
>
> _Optionals_ (aka _maybe_ monad) and _expecteds_ are two **different** monads serving different scenarios.

OK, but I am trying to bridge the concept of F# _railway-oriented programming_ to Prolog, I was not planning on using concepts from Logtalk since I have not used Logtalk.

I know Dan is using Logtalk for his code but also likes _railway-oriented programming_ and from what I gather would like to cleanly split the code into the _happy path_ (code without exception handling) and _unhappy path_ (deals with the error/exceptions) in the same/similar way as done with _railway-oriented programming_.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 2, 2020, 3:00pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/50 "2020-01-02T15:00:02Z")

</div>

> [@EricGT](#):
>
> OK, but I am trying to bride the concept of F# _railway-oriented programming_ to Prolog, I was not planning on using concepts from Logtalk since I have not used Logtalk.

Easy to fix 😛

> [@EricGT](#):
>
> I know Dan is using Logtalk for his code but also likes _railway-oriented programming_ and from what I gather would like to cleanly split the code into the _happy path_ (code without exception handling) and _unhappy path_ (deals with the error/exceptions) in the same/similar way as done with _railway-oriented programming_ .

Note that the [cascade](https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/cascade) example used in the [Handling missing data](https://logtalk.org/2019/11/21/handling-missing-data.html) blog post is an example of _railway-oriented programming_.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 2, 2020, 10:49pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/51 "2020-01-02T22:49:10Z")

</div>

> [@pmoura](#):
>
> That said, adding non-deterministic versions of the `from_goal/3-4` predicates could be useful. Thanks for the feedback.

P.S. Added non-deterministic constructors for both the `expecteds` and `optionals` libraries. From past experience, both in personal work and contract work, I expect these non-deterministic constructors to be used sparingly compared with the deterministic constructors. Still, it will avoid users writing their own versions from the basic constructors if they required them.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [January 3, 2020, 8:39am UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/52 "2020-01-03T08:39:01Z")

</div>

Great.

Would be great if you could also extend one of the blog posts to include an example of their use …

Dan

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [January 3, 2020, 10:05am UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/53 "2020-01-03T10:05:11Z")

</div>

I still have ideas and things I want to add to this topic but will have next to no screen time today so please don’t consider my absence as agreeing or being done with working on this.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 3, 2020, 7:26pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/54 "2020-01-03T19:26:16Z")

</div>

> [@jan](#):
>
> Coding the above is hard though. You get something like this:
> 
> ```prolog
> Error = error(Formal, Context),
> catch(Goal, Error, true),
> ( var(Formal)
> -> <ok, go on>
> ; Formal = existence_error(source_sink, File)
> -> <tell user File does not exist>
> ; ...
> -> ....
> ; <tell user the application is broken and report X to the developers>
> )
> 
> ```
> 
> Some abstraction can make this a little cleaner, but IMO it stays a mess. I’ve been playing with the idea to consider constraints in the catch/3 _ball_ . That would allow for something like
> 
> ```prolog
> environment_error(Error),
> catch(Goal, Error, <tell user about Error>),
> ...
> 
> ```
> 
> And catch all programming errors on the outside of the entire application. Now we can implement a library that defines a (constraint) taxonomy of errors that need to be handled in a specific way.

I would not say _hard_, but I would say _verbose_. Using the ideas from _Railway Oriented Programming_ and an implementation of the _expected_ monad (such as the one in the Logtalk library), we can defined the sequence of steps that we want without using a single conditional **and** then handle all possible errors with a single handler. As a (bit silly) example, assume that we want to parse the contents of a text file as a URL and extract the URL attributes by doing the following steps:

1. Open file.
2. Read file to codes.
3. Convert the codes into an atom.
4. Parse the atom as a URL.

The file may not exist. Reading the file may fail. The file contents may not be a valid URL… Let’s just assume/pretend that different exceptions may be throw at most steps. As the predicates that will be called don’t take or return _expected terms_ we would need to construct and map them as we go from step to step. Additionally, when the order of the arguments of the predicates is not what the mapping predicate expects, we would need to use either lambda expressions or auxiliary predicates. further contributing to verbosity (not the case here, however). Anyway, we could write something like:

```prolog
file_url_attributes(File, Attributes) :-
	expected::from_goal(open(File,read,Stream), Stream, ExpectedStream),
	expected(ExpectedStream)::map(read_stream_to_codes, ExpectedCodes),
	expected(ExpectedCodes)::map(atom_codes, ExpectedAtom),
	expected(ExpectedAtom)::map(parse_url, ExpectedAttributes),
	expected(ExpectedAttributes)::or_else_throw(Attributes).

```

And then do:

```prolog
?- catch(file_url_attributes(File, Attributes), Error, handler(Error)).

```

Where `handler/1` would be defined as:

```prolog
handler(abort) :- ...
...
handler(error(Formal,_)) :- handler_formal(Formal).

handler_formal(existence_error(file, ...)) :- ...
...

```

We could define some object aliases and predicate aliases for a bit more compact code. Still, this solution is arguably much cleaner than a sequence of conditionals, most of them doing step specific error catching and handling as in the skeleton code you wrote.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 3, 2020, 8:35pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/55 "2020-01-03T20:35:05Z")

</div>

Hmm. In my opinion this is not a step forward. In good old plain Prolog I can still do

```prolog
file_url_attributes(File, Attributes) :-
    setup_call_cleanup(
       open(File, read, In),
       ( read_stream_to_codes(In, Codes),
          atom_codes(Atom, Codes),
          parse_url(Atom, Attributes)
       ),
       close(In)).

```

This looks a lot better to me and closes the input stream, Where does that happen in your code?

Now it isn’t really a big thing to call

```
catch(file_url_attributes(File, Attributes), Error, handler(Error)).

```

The expected interface is nice in representing errors as unexpected normal data objects together with similar objects that are expected. So, the expected interface allows for a _stream_ of data objects, some of which are expected and some not. In this example we just want to bail out on an error and the application may want to report certain errors friendly to the user and others adequately to the developers. You don’t want the user to see _“Existence error parse\_url/2. Please retry with a different file name”_ 🙂

The main problem with the above code is that there are several types of exceptions and this catches all of them. In theory, handler/1 can re-throw the ones we are not interested in, but this severely hinders debugging in SWI-Prolog. If an error is uncaught, SWI-Prolog will record a stack trace and start the debugger asap. If the error is caught, SWI-Prolog assumes the application deals with it and thus the stack trace is not recorded and the debugger doesn’t kick in.

So, what I want is a library of related errors the application user might be interested in and an abstraction that allows me to specify I want to catch errors of this class (say _file errors_) and leave other errors unaffected as they do not carry anything the user can fix. This notably suffers from the fact that ISO error terms are organised quite differently. For example, we have `existence_error(source_sink, Name)` that tells me some file is missing as well as `existence_error(procedure, Name/Arity)` that tells me a predicate is missing. That is quite a different thing.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 3, 2020, 8:55pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/56 "2020-01-03T20:55:44Z")

</div>

> [@jan](#):
>
> This looks a lot better to me and closes the input stream, Where does that happen in your code?

You are taking my example **literally** where I’m explicitly trying to illustrate a **class of problems** where you have a _sequence of steps_ where each step can act both on expected data or on an unexpected error or failure from the previous step (using other predicates from the _expecteds_ library). Your alternative code doesn’t provide the same semantics (if you abstract the details of the example) as an error or failure at one of the steps doesn’t give a chance to the next step to handle it and instead jumps directly to the handler.

> [@jan](#):
>
> So, what I want is a library of related errors the application user might be interested in and an abstraction that allows me to specify I want to catch errors of this class (say _file errors_ ) and leave other errors unaffected as they do not carry anything the user can fix.

Thanks for clarifying.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 3, 2020, 9:05pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/57 "2020-01-03T21:05:40Z")

</div>

> [@pmoura](#):
>
> Your alternative code doesn’t provide the same semantics (if you abstract the details of the example) as an error or failure at one of the steps doesn’t give a chance to the next step to handle it and instead jumps directly to the handler.

Yip. The expected interface does allow for that and that is (sometimes) a nice idea. The traditional exception interface just aborts the computation up to some parent willing to deal with the error. That is often also a good plan. Neither addresses distinguishing _who_ is interested in the error. That is probably even more severe for the expected interface. If some early step raises a predicate existence error and it pops up much later in the pipeline, you really have no clue where to start debugging.

That is the issue I would like to improve 🙂

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 3, 2020, 9:15pm UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/58 "2020-01-03T21:15:09Z")

</div>

> [@jan](#):
>
> Neither addresses distinguishing _who_ is interested in the error.

It’s now clear to me that’s the main problem that you are trying to solve.

> [@jan](#):
>
> That is probably even more severe for the expected interface. If some early step raises a predicate existence error and it pops up much later in the pipeline, you really have no clue where to start debugging.

It would depend on how much (or how little) details of the term representing the unexpected error or failure would carry. When calling built-in predicates with their fixed exceptions, that would indeed be an issue. With user-defined predicates, you can plan for richer representations that could make use of some registry that associates classes or errors with interested parties.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [January 4, 2020, 1:06am UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/59 "2020-01-04T01:06:40Z")

</div>

In trying to bridge the idea of _railway-oriented programming_ with Prolog, and with _railway-oriented programming_ originating in F# which is a functional language I have turned to papers that talk about the implementation of functional-logic languages for ideas. This is not to suggest anything at this point, but just to note that these papers get the ideas flowing, e.g. it seems that we are defaulting to the depth-first strategy of Prolog, perhaps a breath-first search is needed for some of the processing (just an idea that popped into my mind when reading a paper).

One I am currently reading, although a bit old is:

[THE RELATION BETWEEN LOGIC AND FUNCTIONAL LANGUAGES: A SURVEY](https://core.ac.uk/download/pdf/82644849.pdf)

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [January 4, 2020, 1:49am UTC](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681/60 "2020-01-04T01:49:49Z")

</div>

> [@EricGT](#):
>
> In trying to bridge the idea of _railway-oriented programming_ with Prolog …

It’s already there via Logtalk. Notably, you can use most Logtalk libraries, including the `expecteds` library, from within plain Prolog or a Prolog module in the same way that you can use Prolog built-in predicates and most Prolog module libraries from within a Logtalk object.

Drawing lines in the sand and acting like there’s a wall serves no useful purpose. In the context of a Prolog system that touts a pack infrastructure and invites contributions, is quite odd. In this particular thread, where we are discussing different semantics for exception handling, portraying those solutions as _us_ versus _them_ it’s just distracting.

[Previous page](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681.md?page=2)

[Next page](https://swi-prolog.discourse.group/t/when-does-assert-fail-running-out-of-space/1681.md?page=4)
