Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Introducing Syngr, my attempt at an Standard Library for PHP (github.com/hassankhan)
35 points by niteshade on Sept 23, 2013 | hide | past | favorite | 51 comments


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.


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.


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 :)


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.


And also, not to nitpick, but namespaces are (still?) basically a joke in PHP, and as for late static binding, well, same boat as you, my friend :)


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!


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


Show us the numbers.

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



So your code is 45.7 times slower.

HAHAHAHA.


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.


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?


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


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.


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


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

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


Absolutely.


Absolutely non-intuitive?


I think the point here is that you'd have to do something like this

  $x = new Number(1)
  $y = clone $x;
  $y->absolute();
to work with the absolute value of variable $x without actually changing $x


Yes, this is a common source of bugs when you're not sure what is changing. See below, someone suggests to use 'to' and 'as' prefix to convey immutable / mutable methods.


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.


This came to mind when I saw what you've created - 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.


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)


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.


not going to happen ,because PHP relies to much on native extensions. If a fork doesnt work with them , it will not be successfull. The best one can do is move to Python , which works on an httpd server and is a real multipurpose language, and it has a lot of support on shared hosts.


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

I'd really like to join forces :)


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();


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.


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).


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


The right acronym would have been SPL


Fixed it, thanks :)


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


Arrays could benefit from a little wrapper


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


not bad, but where getContent();

how about boxed objects?


getContent() is a magic method.

How would I go about adding boxed objects in PHP?


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


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)
            )
        )
    )


I've never really understood the incessant need to replicate idioms from other languages on top of the already existing idioms in PHP.


Incessant? I suppose it is, the language is in real need of it.


I've been using PHP for over 12years now. I even attempted what you are doing once, but via an extension, but quickly realised I was simply complicating things in some misguided attempt to fix which wasn't broken.


I think its ugly?


It's as efficient as you can possibly get with PHP .. how is that ugly? Ugly because it doesn't remind you of Python, Ruby or whichever language you prefer?


Yeah, mostly. Also because its how it should have been done. PHP Internals should strive to clean up PHP to conform to my work ;)


Nothing wrong with that attitude at all! Especially when backed up with code. Keep up the good fight .. but I would suggest you implement this as an extension.


Yeah, I think that'll be the way to go. There's apparently a new way of writing extensions, might've gotten slightly more bearable since you last looked at it :)


I think converting numbers to objects and back is ugly.

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


Well yeah, efficiency wasn't the aim.


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


Don't be a dick, dude.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: