Re: anonymous functions and scope(exit)

2021-07-03 Thread frame via Digitalmars-d-learn

On Saturday, 3 July 2021 at 22:04:04 UTC, Luis wrote:

scope(exit) it's syntactic sugar for a classic `try {} finally 
{}` . The documentation says that must be executed.


It works if you replace printf() with writeln() or use writeln() 
after. There must be some buffer issue.


Re: anonymous functions and scope(exit)

2021-07-03 Thread Luis via Digitalmars-d-learn
On Saturday, 3 July 2021 at 20:46:00 UTC, Steven Schveighoffer 
wrote:

On 7/3/21 4:08 PM, frame wrote:
On Saturday, 3 July 2021 at 17:39:18 UTC, Steven Schveighoffer 
wrote:


But in practice, the compiler does not have to clean up 
anything when an `Error` is thrown. Whether it does or not is 
defined by the implementation.


This should be really mentionend in the docs? "Guard", yeah...




Yeah, there isn't a good discussion of the differences between 
Error and Exception on that page.


-Steve


On [The D Error Handling 
Solution](https://dlang.org/spec/errors.html#the_d_error_handling_solution), says :


If code detects an error like "out of memory," then an Error is 
thrown with a message
saying "Out of memory". The function call stack is unwound, 
looking for a handler for
the Error. Finally blocks are executed as the stack is unwound. 
If an error handler is
found, execution resumes there. If not, the default Error 
handler is run, which displays

the message and terminates the program.


scope(exit) it's syntactic sugar for a classic `try {} finally 
{}` . The documentation says that must be executed.




Re: anonymous functions and scope(exit)

2021-07-03 Thread Luis via Digitalmars-d-learn

On Saturday, 3 July 2021 at 17:47:47 UTC, Dennis wrote:

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

scope(exit) inside of a anonymous functions, it's never called.


I think the compiler infers the function `nothrow` since you 
don't throw any `Exception`, only an `Error`. Errors represent 
unrecoverable bugs, after which the program is in an invalid 
state, so the compiler is free to exit immediately without 
caring about destructors or `scope(exit)`. Use `Exception` 
instead of `Error` if you want the stack to properly unwind.


Indeed, this is happening.

I can reproduce with this :

```d
#!/usr/bin/env dub
/+ dub.sdl:
  dependency "pijamas" version="~>1.1"
+/
import core.exception;

void main()  {
  import core.stdc.stdio;
  import pijamas;

  should(() {
printf("Hello\n");
scope(exit) printf("Bye\n");
throw new RangeError("bla bla");
  }).Throw!RangeError;

  auto f = () {
  printf("Hello\n");
  scope(exit) printf("Bye\n");
  throw new RangeError("bla bla");
};
  f();
}

```

Outputs this :
```
$ f.d
Hello
Hello
core.exception.RangeError@bla bla(20): Range violation

source/f.d:20 nothrow void f.main().__lambda2() [0x5647d46a17db]
source/f.d:22 _Dmain [0x5647d46a1732]
Program exited with code 1
```

If I change the RangeError, by a Exception, then the scope(exit) 
it's executed.


Re: anonymous functions and scope(exit)

2021-07-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/3/21 4:08 PM, frame wrote:

On Saturday, 3 July 2021 at 17:39:18 UTC, Steven Schveighoffer wrote:

But in practice, the compiler does not have to clean up anything when 
an `Error` is thrown. Whether it does or not is defined by the 
implementation.


This should be really mentionend in the docs? "Guard", yeah...




Yeah, there isn't a good discussion of the differences between Error and 
Exception on that page.


-Steve


Re: how much "real-life" code can be marked @safe ?

2021-07-03 Thread tsbockman via Digitalmars-d-learn
On Saturday, 3 July 2021 at 16:06:33 UTC, Alexandru Ermicioi 
wrote:
3. An edge case. Ex: You need to mutate some data and then 
assume it is immutable in a constructor.


Can you give a valid example where that is necessary? The main 
examples that I can think of either can be `@safe` with the right 
API, or are motivated by a desire to avoid the GC and/or 
druntime, thus falling under (1).


4. Functionality that doesn't account for @safe/immutable or 
any other features when it can in standard library.


True, although it's just another example of my point (2). The 
standard library and druntime are dependencies, too...


Take for example array.dup, there is no inout alternative for 
it,
and you're pretty much stuck with trusted code, when you'd like 
to dup an array that is inout.


`inout` is usually just a convenient way to use one 
implementation to handle mutable, `const` and `immutable` cases. 
In those rare cases where `inout` itself won't work, it is almost 
always possible to accomplish the same thing using `template 
this` or separate overloads:


```D
import std.traits : Unqual, CopyConstness;

struct A {
int*[] arr;
this(this This, Arr)(Arr arr) scope pure @safe nothrow
if(is(Arr : E[], E) && is(E : CopyConstness!(This, 
Unqual!E)))

{
this.arr = arr.dup;
}
}

void main()
{
A ma = new int*[5];
const(A) ca = new const(int*[3]);
const(A) ia = new immutable(int*[4]);
}
```

Again, it's certainly not obvious how to do this, or why it is 
necessary, but it is *possible*.


The one exception here is when the array is already typed `inout` 
before it is passed to the constructor. But, that's an example of 
(2) since this logic applies transitively throughout the call 
stack: if you need to call `dup` anywhere, don't erase the 
constness with `inout`.


Re: anonymous functions and scope(exit)

2021-07-03 Thread frame via Digitalmars-d-learn
On Saturday, 3 July 2021 at 17:39:18 UTC, Steven Schveighoffer 
wrote:


But in practice, the compiler does not have to clean up 
anything when an `Error` is thrown. Whether it does or not is 
defined by the implementation.


This should be really mentionend in the docs? "Guard", yeah...




Re: do we already have sum-modulo-10 algo (aka Luhn's algo) on phobos ?

2021-07-03 Thread jfondren via Digitalmars-d-learn

On Saturday, 3 July 2021 at 17:44:48 UTC, someone wrote:

https://en.wikipedia.org/wiki/Luhn_algorithm#Pseudocode_implementation


That specific function, in Phobos? no.

sum modulo 10? That's just some_var%10 in D.

The Wikipedia link ends with a link to RosettaCode:

https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#D
... this is a pretty nice RC entry, translating Haskell, C, and 
SPARK

all into D. Really shows off D's range of expression.


Re: anonymous functions and scope(exit)

2021-07-03 Thread Dennis via Digitalmars-d-learn

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

scope(exit) inside of a anonymous functions, it's never called.


I think the compiler infers the function `nothrow` since you 
don't throw any `Exception`, only an `Error`. Errors represent 
unrecoverable bugs, after which the program is in an invalid 
state, so the compiler is free to exit immediately without caring 
about destructors or `scope(exit)`. Use `Exception` instead of 
`Error` if you want the stack to properly unwind.


Re: anonymous functions and scope(exit)

2021-07-03 Thread jfondren via Digitalmars-d-learn

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

This is intentional ?

...

scope(exit) inside of a anonymous functions, it's never called.


```
$ rdmd --eval 'iota(2).map!((int x) { scope(exit) writeln("got: 
", x); return x+1; }).array.writeln'

got: 0
got: 1
[1, 2]
```

Conclusion: it's not intentional.


do we already have sum-modulo-10 algo (aka Luhn's algo) on phobos ?

2021-07-03 Thread someone via Digitalmars-d-learn

https://en.wikipedia.org/wiki/Luhn_algorithm#Pseudocode_implementation


Re: anonymous functions and scope(exit)

2021-07-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/3/21 1:20 PM, Luis wrote:

This is intentional ?

```
     should(function void() {
     auto emptyStack = SimpleStack!int();
     scope(exit) emptyStack.free; // <= This is never called

     emptyStack.reserve(16);
     emptyStack.top;
     }).Throw!RangeError;
```

scope(exit) inside of a anonymous functions, it's never called.


In principle, it should technically be called.

But in practice, the compiler does not have to clean up anything when an 
`Error` is thrown. Whether it does or not is defined by the implementation.


However, it should *always* work if it's an `Exception` and not an `Error`.

```d

import std.stdio;

void main()
{
auto f = function void() {
scope(exit) writeln("hi");
throw new Exception("boo");
};

f();
}
```

prints "hi"

-Steve


Re: anonymous functions and scope(exit)

2021-07-03 Thread frame via Digitalmars-d-learn

On Saturday, 3 July 2021 at 17:20:47 UTC, Luis wrote:

This is intentional ?

```
should(function void() {
auto emptyStack = SimpleStack!int();
scope(exit) emptyStack.free; // <= This is never 
called


emptyStack.reserve(16);
emptyStack.top;
}).Throw!RangeError;
```

scope(exit) inside of a anonymous functions, it's never called.


Please provide an example code. What lib is this? Normally 
scope(exit) works also for anonymous functions.


anonymous functions and scope(exit)

2021-07-03 Thread Luis via Digitalmars-d-learn

This is intentional ?

```
should(function void() {
auto emptyStack = SimpleStack!int();
scope(exit) emptyStack.free; // <= This is never 
called


emptyStack.reserve(16);
emptyStack.top;
}).Throw!RangeError;
```

scope(exit) inside of a anonymous functions, it's never called.


Re: how much "real-life" code can be marked @safe ?

2021-07-03 Thread Alexandru Ermicioi via Digitalmars-d-learn

On Friday, 2 July 2021 at 22:08:31 UTC, tsbockman wrote:

(Responding out of order:)

On Friday, 2 July 2021 at 00:26:52 UTC, someone wrote:
But when you start attempting to declare @safe chunks of code 
that actually DO things ... well, it seems end-of-the-story.


If you find yourself unable to get real work done in `@safe` 
code, this is almost certainly a sign of one of the following 
problems:


0) You don't fully understand the purpose and valid use of any 
or all of the `@trusted`, `inout`, `scope`, and `return` 
annotations.


1) Your code is avoiding use of the garbage collector, and/or 
does not have `-dip1000` enabled. (`@safe` is still quite 
useful without the garbage collector, but even with `-dip1000` 
you'll still need a lot of `@trusted` code.)


2) You have at least one dependency that isn't correctly 
designed for use with `@safe`.


I'd add:
3. An edge case. Ex: You need to mutate some data and then assume 
it is immutable in a constructor.


4. Functionality that doesn't account for @safe/immutable or any 
other features when it can in standard library. Take for example 
array.dup, there is no inout alternative for it, and you're 
pretty much stuck with trusted code, when you'd like to dup an 
array that is inout.

manual.

Although these two should be on the lowest place in this list by 
priority.





Re: How to select the regex that matches the first token of a string?

2021-07-03 Thread vnr via Digitalmars-d-learn

On Saturday, 3 July 2021 at 09:28:32 UTC, user1234 wrote:

On Saturday, 3 July 2021 at 09:05:28 UTC, vnr wrote:

Hello,

I am trying to make a small generic lexer that bases its token 
analysis on regular expressions. The principle I have in mind 
is to define a token type table with its corresponding regular 
expression, here is the code I currently have:


[...]


storing the regex in a token is an antipattern.


Thank you for the answer,

I know it's not clean, I'll modify my code to define a token type 
table with their regular expression and define a token type table 
with what has match; the former defining the lexer, the latter 
being the result of the latter.


But for now and to keep it simple, I did everything in one.


Re: How to select the regex that matches the first token of a string?

2021-07-03 Thread user1234 via Digitalmars-d-learn

On Saturday, 3 July 2021 at 09:05:28 UTC, vnr wrote:

Hello,

I am trying to make a small generic lexer that bases its token 
analysis on regular expressions. The principle I have in mind 
is to define a token type table with its corresponding regular 
expression, here is the code I currently have:


[...]


storing the regex in a token is an antipattern.


How to select the regex that matches the first token of a string?

2021-07-03 Thread vnr via Digitalmars-d-learn

Hello,

I am trying to make a small generic lexer that bases its token 
analysis on regular expressions. The principle I have in mind is 
to define a token type table with its corresponding regular 
expression, here is the code I currently have:


```d
import std.regex;

/// ditto
struct Token
{
/// The token type
string type;
/// The regex to match the token
Regex!char re;
/// The matched string
string matched = null;
}

/// Function to find the right token in the given table
Token find(Token[] table, const(Captures!string delegate(Token) 
pure @safe) fn)

{
foreach (token; table)
if (fn(token)) return token;
return Token("", regex(r""));
}

/// The lexer class
class Lexer
{
private Token[] tokens;

/// ditto
this(Token[] tkns = [])
{
this.tokens = tkns;
}


override string toString() const
{
import std.algorithm : map;
import std.conv : to;
import std.format : format;

return to!string
(this.tokens.map!(tok =>
format("(%s, %s)", tok.type, 
tok.matched)));

}

// Others useful methods ...
}

/// My token table
static Token[] table =
[ Token("NUMBER", regex(r"(?:\d+(?:\.\d*)?|\.\d+)"))
, Token("MINS", regex(r"\-"))
, Token("PLUS", regex(r"\+")) ];

/// Build a new lexer
Lexer lex(string text)
{
Token[] result = [];

while (text.length > 0)
{
Token token = table.find((Token t) => matchFirst(text, t.re));
const string tmatch = matchFirst(text, token.re)[0];

result ~= Token(token.type, token.re, tmatch);
text = text[tmatch.length .. $];
}
return new Lexer(result);
}

void main()
{
import std.stdio : writeln;

const auto l = lex("3+2");
writeln(l);
}

```

When I run this program, it gives the following sequence:

```
["(NUMBER, 3)", "(NUMBER, 2)", "(NUMBER, 2)"]
```

While I want this:

```
["(NUMBER, 3)", "(PLUS, +)", "(NUMBER, 2)"]
```

The problem seems to come from the `find` function which returns 
the first regex to have match and not the regex of the first 
substring to have match (I hope I am clear enough ).


I'm not used to manipulating regex, especially in D, so I'm not 
sure how to consider a solution to this problem.


I thank you in advance for your help.