Pure and higher-order functions

2012-02-23 Thread mist

Hello!

I have been asked few question recently from a Haskell programmer 
about D2 and, after experimenting a bit, have found that I really 
can't provide a good answe myself, as I am not getting a design 
limititations (if any).


Here is the snippet, it is pretty self-descriptive:
http://codepad.org/DBdCJYI2

Am i right, that all information about purity & Co is lost at 
runtime and there is no way to write pure-aware higher-order 
function using dynamic function pointers? That would have made me 
really sad :(


Re: Pure and higher-order functions

2012-02-23 Thread mist
But is there any way to actually say D compiler that I want this 
function to accept only pure delegates?





Re: Pure and higher-order functions

2012-02-24 Thread mist

Ok, finally understood.

I was trying to declare hof like this: void f2( pure int 
function() param ) , similar to the way I declare usual pure 
functions. Looks like it is syntax error and only void f2( int 
function() pure param ) is allowed. That led me to false 
conclusion, that such signature is not allowed at all.


Are there any reasons for this inconsistency?


Re: Pure and higher-order functions

2012-02-24 Thread mist

Actually, looks like you have done it already 2 years ago :)
http://d.puremagic.com/issues/show_bug.cgi?id=4505


Small code review

2012-06-18 Thread mist

Subj: http://dpaste.dzfl.pl/dfab7219

I wanted to code a small extension to phobos typetuple module to 
extend basic available operations on type tuples more on par with 
std.algorithm ones. I don't have enough practice in 
metaprogramming "D way" though and would gladly listen any 
recommendations in both improving code style and possible ways to 
implement similar things in shorter and more canonical way.


Thanks!


Re: Small code review

2012-06-20 Thread mist

Could you add more details here?
What is current official position? Updating typelist.d and 
merging with typetuple.d? Keeping current one and rewriting some 
algorithms from typelist to work with current TypeTuple?
My point is exactly that it is not that much important how such 
library looks like, but it is only good if included in std lib. 
Too minor to keep as separate library, too generic to copy-paste 
needed in every project required. It is best to just "have it 
here" when you notice that some neat tuple trick can beautify 
this minor part of your code.


I'd gladly to do any stuff that needs to be done to include this 
functionality in Phobos. What are my best options?




You might want to take a look at std.typelist:

https://github.com/D-Programming-Language/phobos/blob/master/std/typelist.d

It's a rather old module which is not actually included in the 
Phobos build
right now (I guess that it never quite made it in, and I'm not 
quite sure what
we're going to do with it). It probably does some of the sort 
of stuff that
you're looking for, though it takes a very different approach. 
If it were to be
fully included as part of Phobos, it would need some updating 
(e.g. fixing how
it names its symbols, since it doesn't always follow Phobos' 
naming
conventions correctly), but it's probably worth your time to 
look at it if

you're really looking to manipulate TypeTuples with algorithms.

- Jonathan M Davis





Trait to get function parameter names

2012-08-31 Thread mist

Subject.
Is that possible? I see only parameter type tuple stuff out 
there. I'm looking into iterating over own parameter name list 
inside of function.


Re: Trait to get function parameter names

2012-08-31 Thread mist

On Friday, 31 August 2012 at 19:15:14 UTC, Jacob Carlborg wrote:

On 2012-08-31 16:24, mist wrote:

Subject.
Is that possible? I see only parameter type tuple stuff out 
there. I'm
looking into iterating over own parameter name list inside of 
function.


Here: http://dlang.org/traits.html#parameterNames


Thank you.


Metaprogramming: check for ref

2012-09-30 Thread mist

How can I:
1) check if function returns by ref
2) check if function parameters are ref
..outside of function body. Is parsing typeof(func).stringof only 
valid option?


Re: Metaprogramming: check for ref

2012-09-30 Thread mist

Thanks!
Unfortunately, return type issue is more important in my case. 
I'll check if implementation from ParameterStorageClassTuple can 
be adapted for return types though.


On Sunday, 30 September 2012 at 20:37:14 UTC, Andrej Mitrovic 
wrote:

On 9/30/12, mist  wrote:

How can I:
1) check if function returns by ref
2) check if function parameters are ref
..outside of function body. Is parsing typeof(func).stringof 
only

valid option?



See ParameterStorageClassTuple in std.traits
http://dlang.org/phobos/std_traits.html

I'm not sure about the return type though. Maybe the template 
should

be improved to add return type into account.


Re: Metaprogramming: check for ref

2012-09-30 Thread mist

Thanks!

On Sunday, 30 September 2012 at 21:20:40 UTC, jerro wrote:

On Sunday, 30 September 2012 at 20:51:54 UTC, mist wrote:

Thanks!
Unfortunately, return type issue is more important in my case. 
I'll check if implementation from ParameterStorageClassTuple 
can be adapted for return types though.


I think this should work:

template returnsRef(alias f)
{
enum bool returnsRef = is(typeof(
{
ParameterTypeTuple!f param;
auto ptr = &f(param);
}));
}




Re: Metaprogramming: check for ref

2012-10-03 Thread mist
On Sunday, 30 September 2012 at 21:34:36 UTC, Andrej Mitrovic 
wrote:

On 9/30/12, jerro  wrote:

I think this should work:

template returnsRef(alias f)
{
 enum bool returnsRef = is(typeof(
 {
 ParameterTypeTuple!f param;
 auto ptr = &f(param);
 }));
}


Yep. We should add this to Phobos imo.


Was pull request fired for this? I'd like to subscribe to get 
noticed when this will be in the phobos. If not, would you mind 
if I add one?


Narrow string is not a random access range

2012-10-23 Thread mist
Was thinking on this topic after seeing this: 
http://stackoverflow.com/questions/13014999/cannot-slice-taker-from-std-range-in-d
Still can't understand rationale here. Why native slicing / 
random access is allowed for narrow strings, but trait explicitly 
negates this?


Re: Narrow string is not a random access range

2012-10-23 Thread mist
On Tuesday, 23 October 2012 at 15:55:23 UTC, Andrei Alexandrescu 
wrote:

On 10/23/12 11:36 AM, mist wrote:

Was thinking on this topic after seeing this:
http://stackoverflow.com/questions/13014999/cannot-slice-taker-from-std-range-in-d

Still can't understand rationale here. Why native slicing / 
random
access is allowed for narrow strings, but trait explicitly 
negates this?


Historical mistake.

Andrei


Is string random access gonna be deprecated some day then or this 
is considered a mistake we need to get used to? :)


Re: Narrow string is not a random access range

2012-10-23 Thread mist
Hm, and all phobos functions should operate on narrow strings as 
if they where not random-acessible? I am thinking about something 
like commonPrefix from std.algorithm, which operates on code 
points for strings.


Re: Narrow string is not a random access range

2012-10-24 Thread mist

On Tuesday, 23 October 2012 at 17:36:53 UTC, Simen Kjaeraas wrote:

On 2012-10-23, 19:21, mist wrote:

Hm, and all phobos functions should operate on narrow strings 
as if they where not random-acessible? I am thinking about 
something like commonPrefix from std.algorithm, which operates 
on code points for strings.


Preferably, yes. If there are performance (or other) benefits 
from
operating on code units, and it's just as safe, then operating 
on code

units is ok.


Probably I don't undertsand it fully, but D approach has always 
been "safe first, fast with some additional syntax". Back to 
commonPrefix and take:


==
import std.stdio, std.traits, std.algorithm, std.range;

void main()
{
auto beer = "Пиво";
auto r1 = beer.take(2);
auto pony = "Пони";
auto r2 = commonPrefix(beer, pony);
writeln(r1);
writeln(r2);
}
==

First one returns 2 symbols. Second one - 3 code points and 
broken string. There is no way such incosistency by-default in 
standard library is understandable by a newbie.


Re: Narrow string is not a random access range

2012-10-24 Thread mist

Actually it is awesome.
But all the code breakage.. eh.


Re: Narrow string is not a random access range

2012-10-24 Thread mist
Ok, just one question to make an official position clear: is 
commonPrefix implementation buggy or it is a conscious decision 
to go for some speed breaking correct operations on narrow 
strings at the same time?


Re: Narrow string is not a random access range

2012-10-24 Thread mist

Thanks, that is exactly what I wanted to clarify.
Can I do pull request for this or do you plan to?


Re: Narrow string is not a random access range

2012-10-24 Thread mist
On Wednesday, 24 October 2012 at 12:03:10 UTC, Jonathan M Davis 
wrote:

On Wednesday, October 24, 2012 13:39:50 Timon Gehr wrote:
You realize that the proposed solution is that arrays of code 
units

would no longer be arrays of code units?


Yes and no. They'd be arrays of code units, but any operations 
on them which
weren't unicode safe would require using the rep property. So, 
for instance,
using ptr on them to pass to C functions would be fine, but 
slicing wouldn't.
It definitely would be a case of violating the turtles all the 
way down
principle, because arrays of code units wouldn't really be 
proper arrays
anymore, but as long as they're treated as actual arrays, they 
_will_ be
misued. The trick is doing something that's both correct and 
reasonably
efficient by default but allows fully efficient code if you 
code with an
understanding of unicode, and to do that, you can't have arrays 
of code units
like we do now. But for better or worse, that doesn't look like 
it's going to

change.

What we have right now actually works quite well if you 
understand the issues

involved, but it's not newbie friendly at all.

- Jonathan M Davis


What about a compromise - turning this proposal upside down and 
requiring something like "utfstring".decode to operate on 
symbols? ( There is front & Co in std.array but I am thinking of 
more tightly coupled to string ) It would have removed necessity 
of copy-pasting the very same checks for all algorithms and move 
decision about usage of code points vs code units to user side. 
Yes, it is does not prohibit a lot if senseless operations, but 
at least it is consistent approach. I personally believe that not 
being able to understand what to await from basic 
algorithm/operation applied to string (without looking at lib 
source code) is much more difficult sitation then necessity to 
properly understand unicode.


Re: Narrow string is not a random access range

2012-10-24 Thread mist
Wait. So you consider commonPrefix returning malformed string to 
be fine? I have lost you here. For example, for code sample given 
above, output is:


==
Пи
П[\D0]
==

Problem is if you use == on code unit you can match only part of 
valid symbol.


is(T == const) for function types

2012-12-25 Thread mist

http://dpaste.dzfl.pl/0cda8d0f

bug or feature?


Re: is(T == const) for function types

2012-12-26 Thread mist

On Wednesday, 26 December 2012 at 00:47:28 UTC, Ali Çehreli wrote:

On 12/25/2012 04:13 PM, bearophile wrote:

Ali Çehreli:


I don't know the answer but this works:


That difference smells of compiler bug :-)

Bye,
bearophilee


Hmmm. I think the compiler is right. That const that is applied 
"at the end" in that syntax is I think allowed only for member 
functions. Otherwise these two work as well:


// These work:
const(void delegate()) deleg;
const void delegate() deleg;

// This is a compilation error:
void delegate() const deleg;


Ali


Yes, looks like I was not checking 
http://dlang.org/declaration.html good enough and assumed C-like 
model where "Type const var" is as legal as "const Type var". 
There is a surprising revelation provided by Kenji in context of 
member variable delegates:


struct Test
{
void delegate() const deleg;
}

void main()
{
static if (is(typeof(Test.deleg) F == delegate))
{
pragma(msg, "Sure, delegate");
static assert( is(F == const) );
}
}

"Delegate type qualifier cannot test directly. You should extract 
function type from it, then test const." (c) Kenji


Copying it here from github for any possible lucky googlers :)


std.range lockstep is not input range but opApply entity. Workarounds?

2012-12-29 Thread mist

I basically want to be able to do stuff like this:
auto result = map!( (a, b) => a+b )( lockstep(range1, range2) );

Are there any standard short ways to wrap an input range around 
struct with opApply (which Lockstep is)?


Also what about redesigning Lockstep as a proper range? I could 
do a pull request but not sure about current intentions.


Re: std.range lockstep is not input range but opApply entity. Workarounds?

2012-12-29 Thread mist
Any objections to documentation update to cross-reference zip and 
lockstep to each other? Was not even searching for first one when 
found lockstep, huh.


On Saturday, 29 December 2012 at 14:19:39 UTC, Simen Kjaeraas 
wrote:

On 2012-48-29 14:12, mist  wrote:


I basically want to be able to do stuff like this:
auto result = map!( (a, b) => a+b )( lockstep(range1, range2) 
);


Are there any standard short ways to wrap an input range 
around struct with opApply (which Lockstep is)?


Also what about redesigning Lockstep as a proper range? I 
could do a pull request but not sure about current intentions.


Use std.range.zip instead:

  auto result = map!( (a, b) => a+b )( zip(range1, range2) );

The reason there are two ways is lockstep works better with 
foreach:


  foreach (a, b; lockstep(A, B) ) {
  // Use a and b here.
  }

Contrast with zip:

  foreach (a; zip(A, B) ) {
  // Use a[0] and a[1] here.
  }

There have been suggestions to better integrate tuples in the 
language,
so in the future zip may have all the advantages of lockstep 
(and vice

versa), but don't cross your fingers.




Re: std.range lockstep is not input range but opApply entity. Workarounds?

2012-12-29 Thread mist

Not clever enough to expand like this though:
map!( (a, b) => a+b )( zip(Range1, Range2) );

Using a => a[0]+a[1] is not that big deal though.

On Saturday, 29 December 2012 at 17:58:55 UTC, Ali Çehreli wrote:

On 12/29/2012 06:19 AM, Simen Kjaeraas wrote:

> foreach (a; zip(A, B) ) {
> // Use a[0] and a[1] here.
> }
>
> There have been suggestions to better integrate tuples in the
language,
> so in the future zip may have all the advantages of lockstep
(and vice
> versa), but don't cross your fingers.

Tuples have already been integrated at least as much: :)

import std.stdio;
import std.range;

void main()
{
int[] cats;
int[] birds;

foreach (cat, bird; zip(cats, birds)) {
writeln(cat, bird);
}
}

Ali




Re: Passing shared delegates

2013-01-11 Thread mist
Do not have time to test code right now but first guess it is 
related to parsing differences for delegates and usual functions. 
Delegates can have shared/const applied to both delegate type 
itself and context of underlying function. Those are different 
beasts and no wonder type system complains.


You may need to try something like "void delegate() shared f" if 
you want delegate type to match method one.


Re: Passing shared delegates

2013-01-14 Thread mist

On Monday, 14 January 2013 at 10:13:16 UTC, Martin Drasar wrote:

On 14.1.2013 8:56, Maxim Fomin wrote:

Which compiler version do you use? It compiles on 2.061.


It was 2.060. It compiles now on 2.061. Great!



Yes, it was a known bug in pre-2.061
Big relief to have it working :)



Re: Mixin Template: cannot mixin scope(exit)?

2013-01-14 Thread mist


It appears that you cannot mixin *any* statement with
scope([exit,success,etc]) in it.

I have been rereading my copy of TDPL, and it states that mixin
statements must be valid D code, and there can be multiple 
'scope()'

statements.

Since "scope(exit) writeln();" is valid D code, and refuses to 
compile

in a mixin, I assume that this is a bug.

I've been digging through the bug tracker and I cannot find a 
duplicate
bug, so if someone can confirm that this is a bug, I'll create 
a report.


It is not a bug. Use a string mixin.


What is the rationale behind this limitation?


Need help with storage class definition

2013-01-14 Thread mist
While working on 
https://github.com/D-Programming-Language/phobos/pull/863 I have 
noticed that inout breaks ParameterStorageClassTuple and family. 
I have started working on a fix but quick comparison of 
http://dlang.org/declaration.html#StorageClass vs 
http://dlang.org/phobos/std_traits.html#.ParameterStorageClassTuple 
have left me in confusion without clear understanding what 
parameter storage classes are supposed to be defined to.


There is also InOutX entry in grammar which lists some of storage 
classes and seems more relevant to parameter storage classes 
(i.e. includes ref).


Can someone give a more structured explanation: what is supposed 
to be a storage class, what is supposed to be a type storage 
class and what - a type qualifier? I'd like to update std.traits 
demanglers to the latest state of things, but grammar description 
does not seem clear enough.


Re: Need help with storage class definition

2013-01-14 Thread mist
Meh, while I was looking for this info in docs kind Kenji simply 
came out and fixed it, leaving no chance to learn :(


Re: Mixin Template: cannot mixin scope(exit)?

2013-01-15 Thread mist
I thought template itself should compile but its statement-like 
instantiation should not.


By the way, if all you want is to split out some generic 
statement block without using dirty string mixins, template 
functions with alias parameters may do.

I.e. http://dpaste.1azy.net/68ad8133

Don't know what about inlining for it though.

Mixin templates are supposed to introduce *declarations* not 
statements.


Eg. even this shouldn't compile, should it?
---
mixin template TimeExecution(T) if(isSomeString!T) {
import std.stdio;
writeln(T); // statement
}
---




Re: UDA syntax

2013-01-17 Thread mist
UDAs very design point is to never change type they are attached 
to.
If you want to inject code in a class/struct at compile-time, 
template mixins are supposed tools.


Re: Operator overloading question

2013-01-21 Thread mist
Do you want to discuss it? :) I have noticed that phobos style 
guidelines favor constraints heavily over static asserts but this 
exactly the example when I am uneasy about such choice: static 
assert can both provide more user-friendly error message here and 
remove some code duplication.


On Monday, 21 January 2013 at 12:27:35 UTC, bearophile wrote:

Nathan M. Swan:


The correct keyword is "opBinary", not "opbinary".


The compiler must give an error message easy to understand in 
similar wrong cases.




http://dpaste.1azy.net/b73ef2cd


This is your code:

Arithmetic opbinary(string op)(Arithmetic rhs)
{
static if(op == "+") return add(rhs);
static if(op == "*") return mul(rhs);
else static assert(0, "Operator "~op~" not implemented");
}


I like to add template constraints, where possible:

Arithmetic opbinary(string op)(Arithmetic rhs)
const pure nothrow if (op == "+" || op == "*")

Bye,
bearophile




Re: Operator overloading question

2013-01-21 Thread mist
Hm, but why can't static assert provide an instantiation trace? I 
can live without error message but duplicating same condition 
twice (one time being part of implementation) hurts my eyes :(


On Monday, 21 January 2013 at 17:16:22 UTC, Ali Çehreli wrote:

On 01/21/2013 08:32 AM, mist wrote:

> phobos style
> guidelines favor constraints heavily over static asserts but
this
> exactly the example when I am uneasy about such choice:
static assert
> can both provide more user-friendly error message here and
remove some
> code duplication.

Agreed but there is a problem with 'static assert' in the 
implementation: We don't know what user code has caused the 
issue. (It is a common problem in C++ templated libraries that 
a hard-to-understand compilation error is produced from inside 
a library function template.)


D's template constraints move the compilation error to the 
exact place of the user code.


void foo(string s)()
if ((s == "hello") || (s == "goodbye"))
{
// ...
}

void main()
{
foo!"howdy"();  // <-- compilation error on this line
}

It is better:

Error: template instance foo!("howdy") foo!("howdy") does not 
match template declaration foo(string s)() if (s == "hello" || 
s == "goodbye")


To be honest, it is kind of obvious in this simple case but 
sometimes the cause of the error is still hard to understand 
even with template consraints.


Ali




Re: Operator overloading question

2013-01-21 Thread mist

On Monday, 21 January 2013 at 18:53:08 UTC, Ali Çehreli wrote:

...
Can you elaborate. I don't see the duplication.

Ali


First we check that parameter is one of allowed ones in 
constraint. Then we do the very same check using the very same 
operator list to actually make a right dispatch. Looks wrong to 
me, we shouldn't need to.


I need to clarify though: I am perfectly aware that constraints 
are superior solution in many cases, especially when it comes to 
multiple overloads for library snippets. But exactly in given 
example static assert feels as better suited.


Re: Pull 1019

2013-01-22 Thread mist

On Tuesday, 22 January 2013 at 09:29:07 UTC, Namespace wrote:
On Friday, 18 January 2013 at 13:13:03 UTC, Jacob Carlborg 
wrote:

On 2013-01-18 14:07, Namespace wrote:

Despite the danger that this annoy you probably:
What about pull 1019
(https://github.com/D-Programming-Language/dmd/pull/1019)? 
I'm still
quite new with Git so I do not know exactly what "1 Fail, 9 
Pending"

means (and why it stands there so long)


It means that the test suite failed. You can click "Details" 
to get more details about what failed.


Ok I observe the pull been a while and have to say that the 
status is always the same: 1 Fails, 9 Pending. I also see that 
it is updated every few hours, but the status is still the same 
every time.

Is this normal? Is that automatically update accordingly?
And how is such a nice test environment integrated into a pull 
request?


It will remain the same until author of the pull request will 
actually take time to fix test errors or whatever fails there. 
AFAIR Brad is the one who should get most gratitude for that nice 
CI suite.


Re: Scope and with

2013-01-23 Thread mist

On Wednesday, 23 January 2013 at 10:43:24 UTC, simendsjo wrote:

On Wednesday, 23 January 2013 at 10:30:08 UTC, Namespace wrote:
But AFAIK scope isn't fully implemented as storage class, or 
am I wrong?


I think you are right. And I think it's the reason using 'in' 
parameters are discouraged.


I remember Kenji telling "in" currently is synonym for "const", 
not "const scope" as is often told.


Re: Pull 1019

2013-01-24 Thread mist
yebblies: Can an auto-ref function pointer/deltegate implicitly 
convert to ref?
9rnsr: To @yebblies : I yet not implement it because this is a 
basic proposal.


IMHO, what he says is that behavior proposed by yebblies is some 
more complicated special cases he is not going to do within this 
pull request to keep things simple.


All pulls are proposals, by the way, it is up to one of core devs 
(other than pull author) to make a decision about merging.


On Wednesday, 23 January 2013 at 23:46:19 UTC, Namespace wrote:

I have now seen something I've probably overlooked before.
Here:
https://github.com/D-Programming-Language/dmd/pull/1019#issuecomment-11836011 
Kenji says, that the pull is a basic _proposal_.


What does this mean? It isn't merged until we made a final 
discussion and decision about that? :/


I thought that this is the solution for all C++ rvalue ref 
problems. Am i wrong?
I'm asking so much because I've been using it already - and I 
love it. Without such thing it is very annoying to work with 
structs.


Re: Getting the parameters of a struct/class constructor

2013-01-24 Thread mist
You can use "magic" functions __ctor and __dtor which actually 
serve as constructor and destructor implementations behind the 
scene.


Example and proof-of-concept: http://dpaste.1azy.net/fd924332

Have no idea if it is explicitly defined by spec somewhere though.