Re: find regex in backward direction ?

2020-12-19 Thread Виталий Фадеев via Digitalmars-d-learn

On Sunday, 20 December 2020 at 04:33:21 UTC, Виталий Фадеев wrote:

On Saturday, 19 December 2020 at 23:16:18 UTC, kdevel wrote:
On Saturday, 19 December 2020 at 12:52:54 UTC, Виталий Фадеев 
wrote:

...


"retro" possible when using simple expression "abc".
For complex "ab\w" or "(?Pregex)" should be parsing: [ "a", 
"b", "\w" ],  [ "(", "?", "P", "", "regex", ")"]..., i 
think.


up.


Re: find regex in backward direction ?

2020-12-19 Thread Виталий Фадеев via Digitalmars-d-learn

On Saturday, 19 December 2020 at 23:16:18 UTC, kdevel wrote:
On Saturday, 19 December 2020 at 12:52:54 UTC, Виталий Фадеев 
wrote:

Goal:
size_t pos = findRegexBackward( r"abc"d );
assert( pos == 4 );



module LastOccurrence;

size_t findRegexBackward_1 (dstring s, dstring pattern)
{
   import std.regex : matchAll;
   auto results = matchAll (s, pattern);
   if (results.empty)
  throw new Exception ("could not match");
   size_t siz;
   foreach (rm; results)
  siz = rm.pre.length;
   return siz;
}

size_t findRegexBackward_2 (dstring s, dstring pattern)
// this does not work with irreversible patterns ...
{
   import std.regex : matchFirst;
   import std.array : array;
   import std.range: retro;
   auto result = matchFirst (s.retro.array, 
pattern.retro.array);

   if (result.empty)
  throw new Exception ("could not match");
   return result.post.length;
}

unittest {
   import std.exception : assertThrown;
   static foreach (f; [_1, 
_2]) {

  assert (f ("abc3abc7", r""d) == 8);
  assert (f ("abc3abc7", r"abc"d) == 4);
  assertThrown (f ("abc3abc7", r"abx"d));
  assert (f ("abababababab", r"ab"d) == 10);
   }
}


Thanks.
But, not perfect.

We can't use reverse, becausу "ab\w" will be "w\ba" ( expect 
matching "abc". revesed is "cba" ).



size_t findRegexBackward_2 (dstring s, dstring pattern)
...
   assert (f ("abc3abc7", r"ab\w"d) == 4);
...


Of course, I using matchAll. But it scan all text in forward 
direction.



  size_t findRegexBackward_1 (dstring s, dstring pattern)


/** */
size_t findRegexBackwardMatchCase( dstring s, dstring needle, 
out size_t matchedLength )

{
auto matches = matchAll( s, needle );
if ( matches.empty )
{
return -1;
}
else
{
auto last = matches.front;
foreach ( m; matches )
{
last = m;
}
matchedLength = last.hit.length;
return last.pre.length;
}
}

Thank!
Fastest solution wanted!

May be... some like a "RightToLeft" in Win32 API...

https://docs.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regexoptions?view=net-5.0#System_Text_RegularExpressions_RegexOptions_RightToLeft

but how on Linux? MS-regex and Linux-regex is identical ?



Re: Flag & byLine confusion.

2020-12-19 Thread Ali Çehreli via Digitalmars-d-learn

On 12/19/20 4:40 PM, Mike Parker wrote:

>> 1. Yes.keepTerminator
>
> This is because of Yes is a struct with an opDispatch template that
> "forwards" to Flag!"keepTerminator".yes. This is the preferred syntax
> and will work with any Flag parameter.

I use Flag a lot but I am always bugged by how ugly the !"foo" part is 
especially compared to Yes.foo. A section I had removed from my DConf 
presentation asked whether we could add opDispatch to templates as well. 
That would allow us to say Flag.foo.


I don't know how we could fit it in the syntax but it could be something 
like this:


template Flag() {
  auto opDispatch(string s)() {
alias opDispatch = FlagImpl!s;
  }
}

Another thought that came to me to solve the same issue was to allow 
string template parameters without needing to write the double quotes:


// Re-purposing the 'static' keyword for fun. :)
template Flag(static string s) {
  // ...
}

So we could either write Flag!"foo" or Flag!foo. Similar to how 
opDispatch would convert unknown symbols to strings. Perhaps like this?


template Flag(opDispatch s) {
  // ...
}

Ali



Re: Flag & byLine confusion.

2020-12-19 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 19 December 2020 at 23:16:00 UTC, Rekel wrote:



Most confusing was the way the documentation (website & 
in-editor) used;

1. Yes.keepTerminator
2. KeepTerminator.yes
3. Flag!"keepTerminator".yes


Your confusion arises from the fact that KeepTerminator is 
combining multiple distinct D features to achieve its goal.


As Paul said, std.typecons.Flag is a templated enum of type bool. 
It's declared to take a string as its template parameter, and it 
has two fields: yes, and no. Minus the documentation:


template Flag(string name) {
///
enum Flag : bool
{
no = false,
yes = true
}
}

The template parameter serves to make Flag!"foo" a distinct type 
from Flag!"bar".


Now, the goal of Flag is to make the purpose of a boolean 
function parameter more clear. Sometimes, we can misremember what 
a boolean parameter indicates. Does true mean do this extra thing 
or does it mean don't do this extra thing? Flag removes the doubt.


However, having to write Flag!"keepTerminator".yes all the time 
is more annoying that simply writing true, so functions that use 
Flag usually have a corresponding alias defined in the module 
scope to give it a less annoying syntax:


alias KeepTerminator = Flag!"keepTerminator";

Because of this, you can write KeepTerminator.yes and 
KeepTerminator.no.


std.typecons also has two structs: Yes and No. Both are 
implemented with a bit of template magic. D supports a feature 
called "Forwarding" in structs and classes and implements it via 
a special template called opDispatch:


https://dlang.org/spec/operatoroverloading.html#dispatch

The idea is that if you call a member function on a struct or 
class, and the class does not have a member function of that 
name, then the compiler will look for an opDispatch template 
implementation in that class or struct. If it finds one, it will 
call the template with the name of the missing function.


There are a number of use cases for this, if you look at the 
examples in the documentation of opDispatch, you'll find that 
there are two examples of implementing it as a function template 
and one that looks like this:


struct D
{
template opDispatch(string s)
{
enum int opDispatch = 8;
}
}

This impelemtation is an enum template that's essentially 
creating an enum with a single member, also called a "manifest 
constant" (a compile-time constant):


https://dlang.org/spec/enum.html#manifest_constants

This is an eponymous template, which means it can be accessed 
directly as opDispatch without using dot notation on the template 
name (opDispatch.opDispatch). So given `d` of type `D`, when the 
compiler sees `d.foo`, it looks for `foo` in the `D` struct. It 
doesn't find it, but it does find `opDisptach`, so it 
instantiated `d.opDispatch!"foo"` which, in this case, produces 
the number `8` as a compile-time constant.


Both the Yes and No structs use this technique:

struct Yes
{
template opDispatch(string name)
{
enum opDispatch = Flag!name.yes;
}
}

So when you call Yes.keepTerminator, you're getting 
Flag!"keepTerminator".yes as a result.


The point behind the structs is so that people who make use of 
Flag in their function parameter lists don't need to actually 
define an alias:


"The structs Yes and No are provided as shorthand for 
Flag!"Name".yes and Flag!"Name".no and are preferred for brevity 
and readability. These convenience structs mean it is usually 
unnecessary and counterproductive to create an alias of a Flag as 
a way of avoiding typing out the full type while specifying the 
affirmative or negative options."


So when implementing your function with a Flag!"foo", you can 
skip the alias and users can call the function with Yes.foo and 
No.foo.


However, I believe that the aliases for KeepTerminator in 
std.string (for splitLines and lineSplitter) and std.stdio (for 
byLine and byLineCopy) predate the implementation of the Yes and 
No structs in std.typecons, but were kept around so as not to 
break any code.


So, to summarize:


1. Yes.keepTerminator


This is because of Yes is a struct with an opDispatch template 
that "forwards" to Flag!"keepTerminator".yes. This is the 
preferred syntax and will work with any Flag parameter.



2. KeepTerminator.yes


This is because KeepTerminator is an alias to 
Flag!"keepTerminator". This syntax will only work on any given 
Flag parameter if the function implementer defines the alias.



3. Flag!"keepTerminator".yes


This is because Flag is a templated enum that takes a string 
parameter and has two members: yes and no. This always works, 
because it's the root feature for which the above two syntaxes 
were implemented as conveniences.


& Don't get me started on the autocomplete trying to get me to 
use KeepTerminator.Flag.yes (VSCode & code-d)


code-d uses DScanner to implement autocompletion. It can get 
confused in certain instances when compile-time features are 
involved. If there isn't 

Re: Flag & byLine confusion.

2020-12-19 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 19 December 2020 at 23:16:00 UTC, Rekel wrote:
After reading most of the tour.dlang.org website, I was 
completely surprised & confused encountering 'KeepTerminator', 
a 'Flag' used by the File.byLine function. With no examples 
denoting how to use it.


Most confusing was the way the documentation (website & 
in-editor) used;

1. Yes.keepTerminator
2. KeepTerminator.yes
3. Flag!"keepTerminator".yes
& Don't get me started on the autocomplete trying to get me to 
use KeepTerminator.Flag.yes (VSCode & code-d)


Flag is a templated enum, documented here:

http://phobos.dpldocs.info/std.typecons.Flag.html

It has two members, Flag!"name".yes and Flag!"name".no. As 
explained in the documentation linked above, Yes and No are 
structs that provide (slightly) less verbose aliases for these 
enum members. The documentation for Yes and No is here:


http://phobos.dpldocs.info/std.typecons.Yes.html
http://phobos.dpldocs.info/std.typecons.No.html

Even further confused by the in-editor documentation, is this 
function a template?:

"
byLine(Terminator = char, Char = char) (KeepTerminator 
keepTerminator = No,keepTerminator, Terminator terminator = 
'\\n')

"


Yes, it is a template. If you look at the section on "parameters" 
in the documentation


http://phobos.dpldocs.info/std.stdio.File.byLine.1.html#parameters

...you can see that the template parameter Char is the character 
type used for the lines. So if you wanted to have lines of wchar 
instead of char, you could use `.byLine!(wchar, wchar)`.


Flag & byLine confusion.

2020-12-19 Thread Rekel via Digitalmars-d-learn
After reading most of the tour.dlang.org website, I was 
completely surprised & confused encountering 'KeepTerminator', a 
'Flag' used by the File.byLine function. With no examples 
denoting how to use it.


Most confusing was the way the documentation (website & 
in-editor) used;

1. Yes.keepTerminator
2. KeepTerminator.yes
3. Flag!"keepTerminator".yes
& Don't get me started on the autocomplete trying to get me to 
use KeepTerminator.Flag.yes (VSCode & code-d)


Now some documentation stated these flags are used to improve 
readability, when compared to simple booleans, but all these 
different notations seem super confusing, especially since I dont 
understand why Flag requires a !"Name" part.
And I haven't read anything about it in the language tour, nor 
have I found any discussion on the topic elsewhere.
I did find, for some reason, a second 'KeepTerminator' 
documentation page . . . which is from std.string, which 
understandably did not help clear things up.


Even further confused by the in-editor documentation, is this 
function a template?:

"
byLine(Terminator = char, Char = char) (KeepTerminator 
keepTerminator = No,keepTerminator, Terminator terminator = '\\n')

"

I'm sorry, I may be asking for too much, but I've got so many 
questions and found few answers.

1. Did I miss some tutorial?
2. Why does flag require a name (!"Name")?
3. Is byLine a template, if so, how would one use it differently?


Re: find regex in backward direction ?

2020-12-19 Thread kdevel via Digitalmars-d-learn
On Saturday, 19 December 2020 at 12:52:54 UTC, Виталий Фадеев 
wrote:

Goal:
size_t pos = findRegexBackward( r"abc"d );
assert( pos == 4 );



module LastOccurrence;

size_t findRegexBackward_1 (dstring s, dstring pattern)
{
   import std.regex : matchAll;
   auto results = matchAll (s, pattern);
   if (results.empty)
  throw new Exception ("could not match");
   size_t siz;
   foreach (rm; results)
  siz = rm.pre.length;
   return siz;
}

size_t findRegexBackward_2 (dstring s, dstring pattern)
// this does not work with irreversible patterns ...
{
   import std.regex : matchFirst;
   import std.array : array;
   import std.range: retro;
   auto result = matchFirst (s.retro.array, pattern.retro.array);
   if (result.empty)
  throw new Exception ("could not match");
   return result.post.length;
}

unittest {
   import std.exception : assertThrown;
   static foreach (f; [_1, 
_2]) {

  assert (f ("abc3abc7", r""d) == 8);
  assert (f ("abc3abc7", r"abc"d) == 4);
  assertThrown (f ("abc3abc7", r"abx"d));
  assert (f ("abababababab", r"ab"d) == 10);
   }
}


Re: Simple BeamUI project won't link

2020-12-19 Thread aberba via Digitalmars-d-learn
On Friday, 18 December 2020 at 19:15:16 UTC, Daren Scot Wilson 
wrote:
On Wednesday, 16 December 2020 at 07:45:50 UTC, Ferhat 
Kurtulmuş wrote:
On Wednesday, 16 December 2020 at 07:40:45 UTC, Ferhat 
Kurtulmuş wrote:


This may be not your issue, but I could manage it to work by 
adding this line:


subPackage "examples/myproject"

to the dub.sdl of the beamui. I simply put my project in 
examples/ folder.


And compile and run using:

dub run :myproject


The thought crossed my mind to try putting my source under 
examples/ but that's not a good way to organize a real project. 
I'd like it be under ~/projects/, naturally. What I want to 
make will involve a lot more than just a GUI.



When BeamUI is released, you wouldn't have to do that. It's still 
wip like you said.



I've been using GTKd on Windows and Linux... including CSS 
styling for getting a pretty looking UI. It works just fine and 
gtkdcoding.com is just the learning resource for getting started.




find regex in backward direction ?

2020-12-19 Thread Виталий Фадеев via Digitalmars-d-learn

We have:
dstring s = "abc3abc7";

Source:
https://run.dlang.io/is/PtjN4T

Goal:
size_t pos = findRegexBackward( r"abc"d );
assert( pos == 4 );


How to find regex in backward direction ?



Re: C++ or D?

2020-12-19 Thread Godnyx via Digitalmars-d-learn

On Thursday, 12 November 2020 at 09:35:10 UTC, hgriffin wrote:
C++ is a really overloaded with features language. The burden 
of backward compatibility and source compatibility with C 
doesn't make it any better. But right now it's the only right 
choice for development. There are plenty of libraries for many 
common tasks, a big community and the most important thing - 
C++ is evolving. Evolution is not as fast as we would want, but 
it's here.
On the other side, D is really pleasant to work with, it has 
many good features and it can be a really convenient tool for 
small projects. But at the same time it's just not mature and 
not suitable for serious development. If you choose it, you'll 
face with lots of issues without a solution. Nobody from the D 
community would help you other than "just don't use const", "we 
haven't developed a concensus yet", "we can't convince Walter", 
etc. You can look at the D's evolution history and approximate 
it into the future. Years go by, nothing's changing. It's 
stagnating. The biggest D's problem is poor management and it's 
not going to change in any foreseeable time.


Hi! Can you be more specific about the problems someone is gonna 
face with D that can't be fixed? This is very important for me 
because I'm planning to use D for development in the near (I wish 
near) future and I want to know what's going on. So yeah some 
examples will be appreciated!