Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I tried to use Go, and then realised I had to write my own contains method for slices and realised that the language is half-baked.


Go is for people that want to build that sort of stuff though. It makes it feel like you’re being productive and scratches that itch as an engineer.

But then yea, 1 line of python using an inbuilt function solves a 10 line go routine in a hackerrank.


I don't think most people who are using Go really want to write their own contains method for slices every time: it seems antithetical to being productive and doing what you actually want to do and it is most definitely a shortcoming of the language. Fortunately with generics people can hopefully need to do that a lot less!


Just in case you forgot: Contains is a (nearly) standard lib function these days. Go did get generics, which are type safe (unlike some other languages I could mention). Before that, you had to write a slightly more clunky function yourself, but it was still a one-liner.

Second: it's not a good function to use. Checking if something is present in an array is not something you should do often and thoughtlessly. It has its uses, I agree, but in general a "dict", or if you really need an array, binary search, should be used. Where's the one liner for that in python? O wait, there isn't one. Go does have it, though, since a long time.

But it's a good thing we no longer use LoC as a measure.


> Where's the one liner for that in python? O wait, there isn't one.

Here it is:

    >>> import bisect
    >>> sorted_fruits = ['apple', 'banana', 'orange', 'plum']
    >>> bisect.bisect_left(sorted_fruits, 'banana')
    1


Note that that finds the index to the left of the insertion point for the value given, but doesn’t perform a containment test; you have to also check that the index is in the list (instead of off the end) and that the value at the resulting index equals the value of interest to test containment. Which can be a one-liner without redundant calls (with walrus), but is a bit ugly.

(Of course, for a custom class you can just wrap it in a __contains__ method and then just use the “in” operator.)


> you have to also check that the index is in the list (instead of off the end) and that the value at the resulting index equals the value of interest to test containment

True. However, the hardest part of the binary search algorithm is implemented through bisect, so it still saves a lot of developer time.


How about a more complex type? Something like a custom class instance?


As long as your type is isomorphic to an array, you can implement __len__() and __getitem__(i) and bisect will still work:

    >>> class C:
    ...     def __len__(self):
    ...             return 10
    ...     def __getitem__(self, i):
    ...             if i >= 10:
    ...                     raise IndexError('out of range')
    ...             return i+1
    ... 
    >>> c = C()
    >>> import bisect
    >>> bisect.bisect_left(c, 1)
    0
    >>> bisect.bisect_left(c, 4)
    3


Or you can implement a binary search in your type's __contains__ and just use `"foo" in c`


You can do that too, using the bisect, provided you have the __len__ and __getitem__ implemented:

    class C:
        def __len__(self): ...
        def __getitem__(self, i): ...
        def __contains__(self, x):
            i = bisect.bisect_left(self, x)
            return i < len(self) and self[i] == x
At that point it's just syntactic sugar.


Thanks!


That looks like three lines to me.


The first two lines are setup, real code would already have done that.

You could maybe count the import, but you'd have to do that once and could do multiple bisections, so it's amortized.

Setting the variable doesn't count because you do, of course, need a variable to perform an operation on a variable. Sorting the array also wouldn't count because you can't use binary search if the array isn't sorted.


> But in general a “dict”, or if you really need an array, binary search, should be used. Where’s the one liner for that in python?

For dict/set hash lookup, O(1):

   x in s
For binary search on a sorted python list, it takes a standard library import (bisect), and the containment test is:

  (i:=bisect.bisect_left(a, x)) < len(a) and a[i] == x


I don't know Go, however checking if an element is in an array, even unsorted, is likely faster than anything involving a linked list or a hash map unless the equality test is very expensive (maybe) if the array is small enough. And it is often small enough. I don't know how small, I guess it depends on the computer and the implementation, but 100 is probably still fine.

So, yes, let's have a contains function on (unsorted) arrays.


Are you really shaming us for wanting to check the contents of an array? god damn.. how can you get anything useful done, or even meet the requirements? What you are proposing goes beyond having your hands tied and being blindfolded.


Loc is a bad code metric when measuring at the scale of codebases. However, when measuring the succinctness of a language it has its place.

And, contains is a perfectly cromulent function to use unless there's a reason not to. At a million items it would be a bad use of contains if you were to lookup up multiple items, but modern day programming requires both knowledge of the code structure and the data.

Yes, python's type hinting is pants.

Go's goals are simplicity, python wants to be the working man's language.


    print("quux" in {"foo", "bar", "baz"})


How does that make the language half-baked? Go didn't have generics until recently which made utility functions like that complicated. C doesn't have them either.


C was created 40 years ago. I wouldn't expect it to have the same feature set as Go. Plus, we already have a language like C, and it's called C.

Go made multiple decisions that make me face palm. It was so close to being a great systems programming alternative.


I want a programming language that’s boring. It should have things that Python has including classes. Fast and compiled. No need to try new things.

A pythonic C++ that doesn’t smell bad.

I wish Go had classes. I like those damn things. Extending a Dog from Animal with all the methods and data in one place is nice.


> A pythonic C++ that doesn’t smell bad.

Obligatory...try Rust?

But actually, try python with mypy and mypyc. It's still a little experimental, but if you stick to simple constructs it works well, and you can compile straight python to fast, static libraries, without using goofy cython syntax.


If by extending you mean that you want to have a type that includes ALL the functionality of another type, without needing to fill in each method, that's already supported.

In your new struct definition, include the desired base type as a member - without giving it a name. That embeds the unnamed member directly, and your new type automatically gets all the interfaces and their underlying implementations. As a python-person I always found this a somewhat odd mechanism, but from a functionality perspective it satisfies what I have wanted to do.

Guess that's what people mean by composability.


You should check out Nim. I wish more people would! https://nim-lang.org/


I like Nim, but it's not for someone who likes classes.


Nim supports classes and methods.


It has methods, but doesn't really have classes. And class-oriented programming is unidiomatic in Nim.


I think you can reasonably represent inheritance using struct embedding, and that's quite idiomatic in Go.


can't you get away with just composing the structs, sure not exactly the same but does a good job still


> C was created 40 years ago.

Closer to 50.


I write mainly in c and like most aspects of it but its the absolute minimum standard for built in library support.

The fact that simple reusable utility functions were/are complicated does make it feel half baked to me too.





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

Search: