

Introducing Syngr, my attempt at an Standard Library for PHP - niteshade
https://github.com/hassankhan/Syngr

======
MattBearman
I once starting building a PHP library that was pretty much identical to this,
I was really excited by the prospect of being able to write beautiful, object
oriented, method chained code. Eventually I was overwhelmed by the sheer scope
of what needed to be done and abandoned it. These days I work (almost)
exclusively in Ruby, and life is good.

I'm not trying to dump on this project, quite the opposite, I hope they
achieve what I was never able to. The point I'm trying to make is that I could
only defend PHP for so long before I had to admit that it's a lost cause, and
other languages are simply a better fit for web development.

Stuff like this should already be part of PHP, but it's not, and I'd bet good
money that it never will be. But hey, we got namespaces and late static
binding, things I've used maybe once each.

~~~
niteshade
Totally agree with you, and just having done the String class, I am appalled
at how many different kinds of return values you can get from methods. If
that's not bad enough, then PHP will throw a curveball at you with its 'this
method may return falsy values'.

That's the kind of thinking I've avoided here, trying to explicitly return a
boolean value, or results.

~~~
MattBearman
Indeed, PHP desperately needs some standardisation. At least with your string
class there'll be no more needle/haystack confusion :)

If I find a bit of free time I'll see if I can contribute anything to this, as
while I've all but abandoned PHP, I'd still like to help bring a library like
this in to existence :)

~~~
niteshade
Your help would be highly appreciated - there's loads to cover yet, and God
knows what other horrors PHP has in store.

As a sidenote, I read somewhere recently that there is some method to the
needle/haystack madness. Basically, for strings, its needle/stack, and for
arrays its stack/needle. Thought I'd share that.

------
sandfox
I know microbenchmarks are generally daft and horribly misapplied, but it
might be worth showing/measuring the difference between using built-in
procedural methods and your OO ones on some some example use cases to stop
people speculating and just to make sure you aren't majorly shooting yourself
in the foot perfomance wise for the benefit of a nice API.

All that aside, kudos!

~~~
niteshade
Funny you mention that, just started working on something now. It's slow, I'll
tell you that much. Noticeably slow? Not so sure.

~~~
rorrr2
Show us the numbers.

I'd expect an order of magnitude slower for most of string and number
operations.

~~~
niteshade
Someone on Reddit did the honours:

[http://www.reddit.com/r/PHP/comments/1my5cv/introducing_syng...](http://www.reddit.com/r/PHP/comments/1my5cv/introducing_syngr_my_attempt_at_an_stl_for_php/)

~~~
rorrr2
So your code is 45.7 times slower.

HAHAHAHA.

------
beberlei
some feedback from me:

1\. the value types are not immutable, which will make it very hard to work
with them on larger scale. You should create new instances instead of
modifying the original ones, keeping the originals intact.

2\. The object hierachy is borked. You are exposing way to much information.
Instead of generically allowing to save values and options in the Object, you
should specialize the types much more and hide the actual value.

3\. You should convert the value when creating the type, using (int) for
example, or throw an exception if not convertable. The current converts the
values at many places, which increases the complexity of the code
unnecessarily.

~~~
niteshade
1\. I had thought about that, but then I thought I'd go sort of like the
Javascript route where everything can be modified (well, mostly, anyway)

2\. Specialise the types more how? Why would I want to hide the actual value -
although I suppose I'd want to make sure that no external object can modify
its value directly.

3\. Like in the constructor? What about for Number, where you can pass it an
int, double or float?

~~~
MattBearman
If you're interested, when I was working on a lib like this, each method had
two versions, to* and as*, eg:

    
    
      $string->to_upper_case() # change the original
      $string->as_upper_case() # keeps original, and returns a new upper case string

------
cabalamat
AIUI, if I do:

    
    
        $x = new Number(-3.2);
        $y = $x->absolute();
    

Then not only is $y equal to 3.2, $x is now 3.2 as well. Is this correct? If
it is, I think it is non-intuitive.

~~~
niteshade
That is correct. What would you expect it to do?

~~~
cabalamat
I would expect $x to remain the same. What's wrong with:

    
    
        $x = -3.2;
        $y = abs($x);

------
ivanhoe
It looks that you don't do any checks if the object is really initialized with
the value of the given type? However, if you did, then one could use this for
a quick & elegant input validation and that would be extremely cool. It should
check the value in the constructor and throw the exceptions if the type is
wrong. And then you will also need more granular types like Integer and Float
to make this more useful for everyday cases.

------
cstrat
This came to mind when I saw what you've created -
[http://xkcd.com/927/](http://xkcd.com/927/)

Although I do believe that there is value in someone forking PHP and
standardising everything in this fashion... just throwing out the legacy
support entirely.

~~~
niteshade
Yeah the idea is to have something that hopefully paves over the rough parts,
and who knows? One day this might be similar to what PHP will look like in the
future (in a galaxy far, far away)

~~~
TazeTSchnitzel
Actually, it is possible that PHP in the near future will look like this. I,
nikic, and some others, want to add methods to primitive types.

------
gh0zt
I like the idea but i don't like the actual implementation. For example:
Number::tan takes an array of flags as an argument but only one flag is ever
used to determine which kind of tangent method is eventually executed. For me
as a user this does not only complicate the usage but it is also potentially
(microoptimizationwise) slower because of the necessary condition check.

So instead of

    
    
      $number = new Number(4.2);
      $number->tan(array(Number::TRIG_ARC))
    

why not just implementing it as a separate method?

    
    
      $number->atan();

~~~
niteshade
Well, PHP has four 'tan' functions, and in all fairness, I might just remove
those functions altogether and leave the basic ones. I do agree that its
longer to type now, but at the expense of remembering WTF atan() does.

~~~
gh0zt
Well, if you need the atan function you probably know what it should do and
apart from that why does the Number:tan method take an array of arguments when
only one is ever used? So at least it should be usable like
tan(Number::Number::TRIG_ARC).

------
eridal
Hey, nice project. I had started something very similar some time ago but I
realized that the oop approach doesn't work quite well as you can't force
other to use your classes. Then I decided to go functional style, where you
receive "kind of" unexpected input but produce predictable output; the result
is a very simple and small api that plays nice with others. Take a look at the
code at [https://github.com/eridal/prelude](https://github.com/eridal/prelude)

I'd really like to join forces :)

------
VMG
STL stands for Standard Template Library -- I think you just mean "Standard
Library"

~~~
agumonkey
The right acronym would have been SPL

------
rnts08
This is great, to bad I left PHP for Python a year or so ago. I'll keep an eye
on this though!

------
agumonkey
Arrays could benefit from a little wrapper

~~~
niteshade
Haha, I just made a commit where I'm going to start adding that.

------
dancecodes
not bad, but where getContent();

how about boxed objects?

~~~
niteshade
getContent() is a magic method.

How would I go about adding boxed objects in PHP?

~~~
dancecodes
Hint: just use container for any php term - but this can unify access I hope.

------
rorrr2
Why would you do this for numbers?

How is

    
    
        $number = new Number(6.9);
        echo $number->ceiling()              // 7
                ->max(array(5, 9, 49.1)) // 49.1
                ->floor()                // 49
                ->sqrt()                 // Value
                ->value();               // Get raw value rather    than string
    

better than writing it in actual functions?

    
    
        sqrt(
            floor(
                max(
                    5, 9, 49.1, ceil(6.9)
                )
            )
        )

~~~
niteshade
I think its ugly?

~~~
rorrr2
I think converting numbers to objects and back is ugly.

And insanely inefficient. For this particular example it must be orders of
magnitude slower.

~~~
rorrr2
OK, if I never need to write insanely slow object oriented code for no good
reason, I will download your "library".

~~~
matthewmacleod
Don't be a dick, dude.

