Discussion:
New "cut" operator (was: Pike 8.0 RC1)
Peter Bortas
2014-11-16 13:40:39 UTC
Permalink
("cut left example"<<" ")=="left example"
("cut left example">>"ex")=="cut left "
NAK. It's a very specific and unobvious use of an operator that
conflict both with both the (unfortunately) adopted C++ iostream
syntax and the more obvious mathematical "much greater|lesser than".

It looks sort of useful but would do well as a functions to make sure
the code is readable. Something like this:

string cutback(string text, string divisor)
{
return (text/divisor)[1..]*divisor;
}

string cutfront(string text, string divisor)
{
return (text/divisor)[0];
}

With better names if possible.
--
Peter Bortas
郭雪松
2014-11-16 16:38:07 UTC
Permalink
Post by Peter Bortas
string cutfront(string text, string divisor)
If pike allows me write code like this:

"<some thing>"->cutfront(">")

I would think cutfront is ok. object oriented you know, the object was always come out first.


Guo Xue Song
Post by Peter Bortas
Date: Sun, 16 Nov 2014 14:40:39 +0100
Subject: Re: New "cut" operator (was: Pike 8.0 RC1)
("cut left example"<<" ")=="left example"
("cut left example">>"ex")=="cut left "
NAK. It's a very specific and unobvious use of an operator that
conflict both with both the (unfortunately) adopted C++ iostream
syntax and the more obvious mathematical "much greater|lesser than".
It looks sort of useful but would do well as a functions to make sure
string cutback(string text, string divisor)
{
return (text/divisor)[1..]*divisor;
}
string cutfront(string text, string divisor)
{
return (text/divisor)[0];
}
With better names if possible.
--
Peter Bortas
Martin Bähr
2014-11-16 16:58:56 UTC
Permalink
Post by 郭雪松
Post by Peter Bortas
string cutfront(string text, string divisor)
"<some thing>"->cutfront(">")
I would think cutfront is ok. object oriented you know, the object was always come out first.
this is actually one of the things i miss in pike.

i'd love
string_value->function(args ...);
to be syntax sugar for:
String.function(string_value, args ...);
same for other types.

greetings, martin.
--
eKita - the online platform for your entire academic life
--
chief engineer eKita.co
pike programmer pike.lysator.liu.se caudium.net societyserver.org
BLUG secretary beijinglug.org
foresight developer foresightlinux.org realss.com
unix sysadmin
Martin Bähr working in china http://societyserver.org/mbaehr/
郭雪松
2014-11-18 12:10:54 UTC
Permalink
Post by Martin Bähr
this is actually one of the things i miss in pike.
I wish there are multiset/mapping/array compared by values.

I wrote a ByValue.pmod to implement this, but still want a native one, must inherit ByValue.Item is boring.

$ cat ByValue.pmod/module.pmod
#! /bin/env pike
class Array(mixed ... a)
{
mixed `[](int pos){ return a[pos];}
mixed `[]=(int pos,mixed val){ return a[pos]=val;}
int _sizeof()/*{{{*/
{
return sizeof(a);
}/*}}}*/
int `==(object rhd)/*{{{*/
{
if(!objectp(rhd))
return 0;
return equal(a,rhd->a);
}/*}}}*/
int `<(object rhd)/*{{{*/
{
if(sizeof(a)==sizeof(rhd->a)){
if(sizeof(a)==0)
return 0;
if(a[0]<rhd->a[0])
return 1;
else if(a[0]==rhd->a[0])
return .Array(@a[1..])<.Array(@rhd->a[1..]);
else if(a[0]>rhd->a[0])
return 0;
}
}/*}}}*/
object `-(object rhd)/*{{{*/
{
object res=.Array(@allocate(sizeof(a)));
for(int i=0;i<sizeof(a)&&i<sizeof(rhd->a);i++){
res->a[i]=a[i]-rhd->a[i];
}
return res;
}/*}}}*/
object `+(object ... args)/*{{{*/
{
object res=.Array(@allocate(sizeof(a)));
for(int i=0;i<sizeof(a);i++)
res->a[i]=a[i];
foreach(args,object rhd){
for(int i=0;i<sizeof(res->a)&&i<sizeof(rhd->a);i++){
res->a[i]=res->a[i]+rhd->a[i];
}
}
return res;
}/*}}}*/
int __hash()/*{{{*/
{
return hash_value(predef::`+(0.0,@map(a,hash_value)));
}/*}}}*/
string _sprintf(int t)/*{{{*/
{
if(t=='O'){
array aa=({});
foreach(a,mixed v){
aa+=({sprintf("%O",v)});
}
return "Array("+aa*","+")";
}
}/*}}}*/
}
class Pair{
inherit .Array;
void create(mixed first,mixed second)/*{{{*/
{
::create(first,second);
}/*}}}*/
string _sprintf(int t)/*{{{*/
{
if(t=='O'){
array aa=({});
foreach(a,mixed v){
aa+=({sprintf("%O",v)});
}
return "Pair("+aa*","+")";
}
}/*}}}*/
}
class Set{
inherit .Array;
void create(mixed ... args)/*{{{*/
{
::create(@sort(args));
}/*}}}*/
string _sprintf(int t)/*{{{*/
{
if(t=='O'){
array aa=({});
foreach(a,mixed v){
aa+=({sprintf("%O",v)});
}
return "Set("+aa*","+")";
}
}/*}}}*/
}
int sn;
int autoid()
{
return ++sn;
}
class Item{
int _byvalue_item_id=.autoid();
int `<(object rhd)/*{{{*/
{
if(Program.inherits(rhd,Item)){
return _byvalue_item_id<rhd->_byvalue_item_id;
}
}/*}}}*/
int __hash()/*{{{*/
{
return hash_value(_byvalue_item_id);
}/*}}}*/
string _sprintf(int t)/*{{{*/
{
if(t=='O'){
return "ByValue.Item("+_byvalue_item_id+")";
}
}/*}}}*/
}



Guo Xue Song
Post by Martin Bähr
Date: Sun, 16 Nov 2014 17:58:56 +0100
Subject: Re: New "cut" operator (was: Pike 8.0 RC1)
Post by 郭雪松
Post by Peter Bortas
string cutfront(string text, string divisor)
"<some thing>"->cutfront(">")
I would think cutfront is ok. object oriented you know, the object was always come out first.
this is actually one of the things i miss in pike.
i'd love
string_value->function(args ...);
String.function(string_value, args ...);
same for other types.
greetings, martin.
--
eKita - the online platform for your entire academic life
--
chief engineer eKita.co
pike programmer pike.lysator.liu.se caudium.net societyserver.org
BLUG secretary beijinglug.org
foresight developer foresightlinux.org realss.com
unix sysadmin
Martin BÀhr working in china http://societyserver.org/mbaehr/
Chris Angelico
2014-11-18 12:16:04 UTC
Permalink
Post by 郭雪松
Post by Martin Bähr
this is actually one of the things i miss in pike.
I wish there are multiset/mapping/array compared by values.
Can you simply use equal() rather than == when you want to compare values?

ChrisA
郭雪松
2014-11-18 12:24:33 UTC
Permalink
Consider this:

Howto create a array of multiset, every item of the array should be uniq. using ByValue, I do it like this:

array res=({});
multiset done=(<>);
for(int i=0;i<100;i++){
for(int j=0;j<100;j++){
int t=random(100);
object ob=ByValue.Set(i,j,t);
if(!done[ob])
res+=({(<i,j,t>)});
}
}

If we do not use ByValue, but using equal() manually, It's much complacated and boring.

Guo Xue Song
Date: Tue, 18 Nov 2014 23:16:04 +1100
Subject: Re: Wishing well
Post by 郭雪松
Post by Martin Bähr
this is actually one of the things i miss in pike.
I wish there are multiset/mapping/array compared by values.
Can you simply use equal() rather than == when you want to compare values?
ChrisA
Chris Angelico
2014-11-18 12:27:53 UTC
Permalink
Post by 郭雪松
Howto create a array of multiset, every item of the array should be uniq.
array res=({});
multiset done=(<>);
for(int i=0;i<100;i++){
for(int j=0;j<100;j++){
int t=random(100);
object ob=ByValue.Set(i,j,t);
if(!done[ob])
res+=({(<i,j,t>)});
}
}
Hmm. Seems an unusual thing to do... although this is a contrived
example, and they never look particularly impressive.

Are you able to represent the sets as strings? An array (or multiset)
of strings is pretty efficient and easy to work with.

ChrisA
郭雪松
2014-11-18 12:39:00 UTC
Permalink
Beleave me, ByValue.pmod is almost the most useful pmod I ever wrote.

The reason not convert to string is most likely the items are objects. and they come from another module out of our control.

Guo Xue Song
Date: Tue, 18 Nov 2014 23:27:53 +1100
Subject: Re: Wishing well
Post by 郭雪松
Howto create a array of multiset, every item of the array should be uniq.
array res=({});
multiset done=(<>);
for(int i=0;i<100;i++){
for(int j=0;j<100;j++){
int t=random(100);
object ob=ByValue.Set(i,j,t);
if(!done[ob])
res+=({(<i,j,t>)});
}
}
Hmm. Seems an unusual thing to do... although this is a contrived
example, and they never look particularly impressive.
Are you able to represent the sets as strings? An array (or multiset)
of strings is pretty efficient and easy to work with.
ChrisA
Chris Angelico
2014-11-18 12:44:32 UTC
Permalink
Post by 郭雪松
Beleave me, ByValue.pmod is almost the most useful pmod I ever wrote.
The reason not convert to string is most likely the items are objects. and
they come from another module out of our control.
Sure, no problem. Like I said, contrived examples don't always carry
the import of the real-world situation they're representing.

I'm not sure this really wants to be a built-in, though. It seems
specialized enough that your ByValue.pmod is the most logical place
for the code.

ChrisA
郭雪松
2014-11-18 12:52:57 UTC
Permalink
If the items are objects that is come from the other module not writen by ourself, We cannot force the items inherit ByValue.Item.

Without inheriting ByValue.Item, `<() not works; Without `<(), a ByValue.Set object cannot be put into a multiset.

In this case, the example I gave totally not work.

Even if the objects come from our module, we don't want to modify it, for modular design reason.

Guo Xue Song
Date: Tue, 18 Nov 2014 23:44:32 +1100
Subject: Re: Wishing well
Post by 郭雪松
Beleave me, ByValue.pmod is almost the most useful pmod I ever wrote.
The reason not convert to string is most likely the items are objects. and
they come from another module out of our control.
Sure, no problem. Like I said, contrived examples don't always carry
the import of the real-world situation they're representing.
I'm not sure this really wants to be a built-in, though. It seems
specialized enough that your ByValue.pmod is the most logical place
for the code.
ChrisA
郭雪松
2014-11-16 16:35:05 UTC
Permalink
Post by Peter Bortas
string cutfront(string text, string divisor)
If pike allows me write code like this:

"<some thing>"->cutfront(">");

I would think cutfront() is ok. Object-oriented you know, the object was always coming out first.


Guo Xue Song
Post by Peter Bortas
Date: Sun, 16 Nov 2014 14:40:39 +0100
Subject: Re: New "cut" operator (was: Pike 8.0 RC1)
("cut left example"<<" ")=="left example"
("cut left example">>"ex")=="cut left "
NAK. It's a very specific and unobvious use of an operator that
conflict both with both the (unfortunately) adopted C++ iostream
syntax and the more obvious mathematical "much greater|lesser than".
It looks sort of useful but would do well as a functions to make sure
string cutback(string text, string divisor)
{
return (text/divisor)[1..]*divisor;
}
string cutfront(string text, string divisor)
{
return (text/divisor)[0];
}
With better names if possible.
--
Peter Bortas
Martin Bähr
2014-11-16 15:35:47 UTC
Permalink
Post by Peter Bortas
("cut left example"<<" ")=="left example"
("cut left example">>"ex")=="cut left "
NAK. It's a very specific and unobvious use of an operator that
conflict both with both the (unfortunately) adopted C++ iostream
syntax and the more obvious mathematical "much greater|lesser than".
well, it's kind of left-shift and right-shift for bits.
still somewhat unobvious, because obvious would be a number of positions to
shift which is not much different from array indexing:

"cut left example" << 4 == "left example" == "cut left example"[4..]

if string|array << int is defined as shift by that number of characters then
string << string could be defined as shift to the first occurrence of that string.
but with that definition i'd expect
"cut left example" << " " == " left example"
because it should be equivalent to:
"cut left example" << search("cut left example", " ");

more interesting would be a form of split where only the first occurance (or
the last) is split away, and both parts are returned.

greetings, martin.
--
eKita - the online platform for your entire academic life
--
chief engineer eKita.co
pike programmer pike.lysator.liu.se caudium.net societyserver.org
BLUG secretary beijinglug.org
foresight developer foresightlinux.org realss.com
unix sysadmin
Martin Bähr working in china http://societyserver.org/mbaehr/
郭雪松
2014-11-16 16:18:07 UTC
Permalink
Post by Martin Bähr
"cut left example" << " " == " left example"
That is useless.

what I really need is the feature of "between", just like this:

"<some thing>"<<"<">>">" == "some thing"

"<title>TITLE</title>"<<"<">>">"=="titile"
"<title>TITLE</title>"[sizeof("title")+2..]=="TITLE</title>"
"TITLE</title>">>"<"=="TITLE"
"TITLE</title>"[sizeof("TITLE")..]=="</title>"


Guo Xue Song
Post by Martin Bähr
Date: Sun, 16 Nov 2014 16:35:47 +0100
Subject: Re: New "cut" operator (was: Pike 8.0 RC1)
Post by Peter Bortas
("cut left example"<<" ")=="left example"
("cut left example">>"ex")=="cut left "
NAK. It's a very specific and unobvious use of an operator that
conflict both with both the (unfortunately) adopted C++ iostream
syntax and the more obvious mathematical "much greater|lesser than".
well, it's kind of left-shift and right-shift for bits.
still somewhat unobvious, because obvious would be a number of positions to
"cut left example" << 4 == "left example" == "cut left example"[4..]
if string|array << int is defined as shift by that number of characters then
string << string could be defined as shift to the first occurrence of that string.
but with that definition i'd expect
"cut left example" << " " == " left example"
"cut left example" << search("cut left example", " ");
more interesting would be a form of split where only the first occurance (or
the last) is split away, and both parts are returned.
greetings, martin.
--
eKita - the online platform for your entire academic life
--
chief engineer eKita.co
pike programmer pike.lysator.liu.se caudium.net societyserver.org
BLUG secretary beijinglug.org
foresight developer foresightlinux.org realss.com
unix sysadmin
Martin BÀhr working in china http://societyserver.org/mbaehr/
Martin Bähr
2014-11-17 17:36:03 UTC
Permalink
Post by 郭雪松
Post by Martin Bähr
"cut left example" << " " == " left example"
That is useless.
well, yes, but it demonstrates why << and >> are not a good fit for this operation.

consider "cut left example" << "left"

i would not expect this to return " example", but instead i would expect "left example"
Post by 郭雪松
"<some thing>" << "<" >> ">" == "some thing"
"<title>TITLE</title>" << "<" >> ">"=="titile"
"<title>TITLE</title>"[sizeof("title")+2..]=="TITLE</title>"
"TITLE</title>" >> "<"=="TITLE"
"TITLE</title>"[sizeof("TITLE")..]=="</title>"
even with added spaces those examples don't feel very readable.

consider instead:

string chomp(string in, void|string cutleft, void|string cutright);
{ /* implementation of this function is left to the reader */ }

chomp("<some thing>", "<", ">") == "some thing";
chomp("<title>TITLE</title>", ">", "<") == "TITLE";
chomp("TITLE</title>", 0, "<") == "TITLE";
chomp("TITLE</title>", "TITLE") == "</title>";

greetings, martin.
--
eKita - the online platform for your entire academic life
--
chief engineer eKita.co
pike programmer pike.lysator.liu.se caudium.net societyserver.org
BLUG secretary beijinglug.org
foresight developer foresightlinux.org realss.com
unix sysadmin
Martin Bähr working in china http://societyserver.org/mbaehr/
Chris Angelico
2014-11-16 14:46:57 UTC
Permalink
Post by Peter Bortas
("cut left example"<<" ")=="left example"
("cut left example">>"ex")=="cut left "
NAK. It's a very specific and unobvious use of an operator that
conflict both with both the (unfortunately) adopted C++ iostream
syntax and the more obvious mathematical "much greater|lesser than".
It looks sort of useful but would do well as a functions to make sure
string cutback(string text, string divisor)
{
return (text/divisor)[1..]*divisor;
}
string cutfront(string text, string divisor)
{
return (text/divisor)[0];
}
With better names if possible.
I'd be inclined to do the first job with sscanf:

sscanf("cut left example","%*s %s",string result) --> result=="left example"

It might be nice to have something like this available, but I agree
that << and >> are bad choices. They're primarily bit shift operators,
and the C++ iostream syntax is already highly abusive. Using operators
in place of function calls seldom works - it's cute, perhaps, but it
often leads to problems. Compare Python's printf-style formatting with
Post by Peter Bortas
"Hello, %s!" % "world"
'Hello, world!'
Post by Peter Bortas
sprintf("Hello, %s!", "world");
(1) Result: "Hello, world!"

Sure, the first one's cleaner... but then it has crazy edge cases with
tuple parameters and trying to cope with more than just one additional
parameter (the operator's binary, the function's variadic), so the
second is much more consistent. In this case, it's not going to run
into that particular problem, but the use of operators for anything
other than their original meaning needs a LOT of justification.
Dividing strings by strings to produce arrays of strings? That's still
division, that makes sense. I like that. Left shifting a string by a
string to push it past some boundary? Hmmmmmmm.... dubious.

ChrisA
Mirar @ Pike importmöte för mailinglistan
2014-11-18 12:45:01 UTC
Permalink
I usually do this:

array res=({});
mapping done=([]);
for(int i=0;i<100;i++)
{
for(int j=0;j<100;j++)
{
int t=random(1);
string key=sort((array(string))({i,j,t}))*",";
if(!done[key])
{
res+=({(<i,j,t>)});
done[key]=1;
}
}
}

I do cast to string for cache-keys a lot. (And I usually use mappings
when I want a hashtable.)
郭雪松
2014-11-18 13:04:04 UTC
Permalink
Post by Mirar @ Pike importmöte för mailinglistan
string key=sort((array(string))({i,j,t}))*",";
I do cast to string for cache-keys a lot. (And I usually use mappings
when I want a hashtable.)
This is detail of implement, most likely perl programmers do this a lot.
I think a programmer speak pike should say "if ({i,j,t}) is done", not "if sort((array(string))({i,j,t}))*"," is done".

But we can't, so its not good.
Mirar @ Pike importmöte för mailinglistan
2014-11-18 12:45:02 UTC
Permalink
I make sure my objects have a cast-to-string method, have an id method
for this purpose or at least do a useful sprintf("%O"). But I never
use objects out of my control.
郭雪松
2014-11-18 13:22:29 UTC
Permalink
But I never use objects out of my control.
This is why Pike lost the competition with Python.

BTW. I wish pike has a cudamat http://code.google.com/p/cudamat/

Guo Xue Song
Subject: RE: Wishing well
Date: Tue, 18 Nov 2014 12:45:02 +0000
I make sure my objects have a cast-to-string method, have an id method
for this purpose or at least do a useful sprintf("%O"). But I never
use objects out of my control.
Loading...