HN user

tef____

51 karma
Posts0
Comments27
View on HN
No posts found.
How Design Works 14 years ago

design, like engineering is about tradeoffs, and flourishes in the presence of constraints. unlike engineering it is often about the cross-domain trade offs.

it's a nice love note to design, written by someone who has learned more css than information design.

the pie charts are terrible (i'm totally sure he interviewed dieter rams and asked him to put a numerical quantity on the importance of his principles).

I can't see a way anyone can interpret the data accurately from the charts he's written.

the pie charts are misleading, the bar charts use two different proportions of responses (engineers vs 'biz'). the axes aren't labeled properly (is it % is it number of responses).

as much as it says that in a fielding-style rest system the URLs and verbs are opaque, he spends a lot of time nitpicking over the format of urls.

unless the resource in question is exposed as an endpoint, the url and verb are handled by the link or form discovered by the client, and invisible to the client.

as for versioning - versioning the mime types is a useful thing, but it does still make sense to use a different url if you are using different links and forms to navigate the service.

I would have preferred to see an extended read-only period, rather than a month in which to panic-download your data (and the export functionality seems to be broken right now too https://convore.com/export ).

I'd really like it if there was more time to capture the site and submit copy to the internet archive. I'll see what I can do with archive team.

So long, and thanks for all the data! Perhaps convore is an apt name for something that consumes your history. :-)

A language used by beginners is not the same as one designed for beginners.

I would wager that a language designed for beginners wouldn't have so much inconsistency, nor dump the user in a world of security issues with little or no support (XSS, CSRF, SQL injection).

Other people have worked around these issues, but that demonstrates the lack of support within the language.

To echo your sentiment, It's a bit like measuring writers not by the books they have written, but how long they've sat in front of a keyboard.

Anecdotally, Not only is time a a poor measure of ability, those who use it as such demonstrate a lack of accomplishment. Compare those who write "N years of Language X" vs "Wrote A,B,C in Z using ...".

I find "I've used X for N years" to mean "I've done one year of X over and over and over" :-)

"the semantics of his library are reasonably clear on inspection"

does .remove() mutate in place or not ? depends on the constructor!

this would be an example of breaking composition - you can no longer use a function built for an immutable list on a mutable list. I am sure I explained this too.

a dialect is a style, in linguistic terms, if I speak a dialect of english, I still speak english.

if I needed a different parser/interpreter I am pretty sure that is the stage of 'new language' where new syntax and semantics are introduced.

the 'dialect' he is introducing is a arc/clojure inspired syntax for what /already/ exists in python.

thanks for the semantic pedantry! the long and the short of it is that if you want to write python, write python that looks like python. not like scheme or clojure.

as someone who gets paid to maintain shitty code, i'd rather people stuck to the existing idioms of the language, rather than blindly copy paste them from another language.

writing your own dialect of the language can be fun, but he is presenting his own style as 'pythonic' as opposed to the actual pythonic style built from functional composition - rather than method chaining.

I am banging on about a lot of the points because it seems very hard to explain to him that using clojure/arc/jquery styles is very very unpythonic.

so you're admitting you're writing an incompatible dialect of python in python?

that was my point. if you think it is worthwhile, well - enjoy :-)

if you want to write in something with a uniform syntax, use scheme or clojure. python things look different for a reason.

tl;dr: you didn't read my post. I am pretty sure I made it clear how composition breaks.

'people are allowed to write Python however they want.'

people are encouraged to write python other people understand.

you seem to go a long way to reinvent python builtins like reverse() any() all() enumerate(), itertools and functors. another python style you violate is that mutable methods return None in general.

from the outset you haven't made any attempt to learn python style. go and read the zen of python.

I only picked on a handful of examples, but wait! theres more - almost every example on your page has a way to do it in python. that other python developers use and understand.

#chaining example:

you say 'we believe chaining constructs are easier to read and maintain than deeply nested expressions.'

zen: flat is better than nested

> Dict(a=1, b=2).update(c=3).rem(lambda x, y: x=='a')

becomes

> d = dict(a=1, b=2)

> d['c'] = 3

> del d['a']

#'partial application' example

> List([1,2,3]).map(string.zfill, 8, _)

becomes

> [str(i).zfill(8) for i in [1,2,3])

# magic argument names

zen: 'explcit is better than implicit'

different methods have different magic attached: it isn't obvious from the outset why update takes named args but keep takes args are named operators

> List([1,2,3]).keep(gt=1)

becomes

> [x for x in [1,2,3] if x > 1]

# you reinvent all

> List(range(1,10)).all(lambda x: x < 100))

becomes

> all(x < 100 for x in range(1,10))

# 'compact' example

> List([None, 0, 2, []]).compact()

becomes

> [x for x in [None, 0 , 2, []] if x]

# 'list is empty' example

> List([]).empty()

becomes

> bool([])

# 'sort'

> List([5,3,1]).sort()

becomes

> sorted([5,3,1])

'uniq'

> List([1,1,2,3,2,1]).uniq().sort()

becomes

> collections.Counter([1,1,2,3,2,1])

for every example you give, there is an equivalent piece of python code to do it, designed in mind with the rest of python. the built in operations give you flexible control over the evaluation too - you can have generator expressions and list expressions. many iterable versions of the standard operators exist in itertools.

really, this is the least pythonic thing since ruby came out. it seems I can only spell this out to you by elaborating through your jquery library and presenting you with python code python developers understand.

please stop re-inventing python without trying to understand why it looks that way first.

if you are inventing a new way to do existing things outside the idioms of the language there is no conceivable way you can claim to be pythonic.

you are replacing the pythonic style with your own taste.

don't confuse the two.

#1 the correct way to do it is to have the methods perform the same action on mutable and immutable objects.

this is the only way to guarantee composition. you do not change the semantics of shared methods.

#2

for both of these examples you give 'to use whatever you want'

"".join(['a','b']) is how everyone else does it in python code.

it isn't about things in the community being usable within your library, it is about your library being /unusable/ within the community. You re-invent new and awkward ways to do standard things without standard idioms.

'i've just invented a whole bunch of new semantics for things so it will be readable'

readability is about /convention/. readable to whom? pushing your own love of jquery method chaining only serves to ostracise those already somewhat knowledgable within python.

it is not pythonic in any way shape of form.

You've invented your own incompatible dialect of python. You've broken composition, objects and the general design choices of python.

1. You break Composition

Your magic flag within a list changes all the semantics of the methods between immutable and mutable lists.

> x = List([1,2,3]).saving()

So now, if you're passed a list you have no idea if the operations you do will mutate the list.

This breaks composition entirely. You can't pass a mutable list into a function built for immutable lists without destroying things.

2. You break objects

Picking another example, this breaks duck typing and inheritance and polymorphism.

>def user_logged(users): > return List(users).all(User.is_logged)

this does not have the same semantics as:

> def user_logged(users): > return all(user.is_logged() for user)

Because the method lookup is done per instance, rather than assuming everything is the same class.

3. You're writing jquery in python

Python chose not to demand that all iterables implement a series of operators, but provides them as functions within a module. The rationale is that it is easier to add new functions within itertools, and there is far less to do to correctly implement the iterator protocol

You can see this in the "".join(foo) operator too. Instead of demanding all iterables support join, string takes an iterable as argument.

Making readable and maintainable python comes from using the existing idioms within the language and used within the community. Your proposed solution isn't readable, and it isn't pythonic.

''Try/catch is goto wrapped in pretty braces.''

From this I can infer that lambda is also an anti pattern.

But as good as this straw man post is, yes you can mis-use exceptions, No that doesn't make it an anti pattern.

As a guy on the internet I am pretty sure she didn't make it up.

I think we will have to wait for confirmation, but not long.

I think this is a good idea. PHP solves a niche of small sites with slightly dynamic templates.

(To some extent it owes more to rebol than to php - it has a large grammar and a notable amount of literals.)

It makes first class what other languages embed in strings - sql, urls, html, etc. In doing so it can solve a large class of security problems that plague many php projects - you don't need to worry about sql injection when the language handles the query parsing.

PHP was successful for a number of reasons, one of which was that it was embedded and exposed a number of cgi specific features into the language ($GET, $POST, etc), this continues in this vein to embrace urls, sql and html as part of the language. The programmer no longer has to deal with escaping or transforming or sanitising strings. This is cool.

Given it runs on the jvm - it should be possible to layer this atop of heroku or google app engine without worrying too much either.

This approach isn't new either - philip wadler tried in a similar way with the functional language 'links'.

(disclaimer: I think php is a terrible, terrible implementation of some good ideas - the library, language and implementation are notable examples of bad ideas in programming)

It is an old question 'How do we tell truths that might hurt?'.

If you try the well reasoned analysis, you get passed over. It turns out that no-one pays attention unless there is a fight happening (c.f. tech crunch's reporting style)

'If the truths are sufficiently impalatable, our audience is psychically incapable of accepting them and we will be written off as totally unrealistic, hopelessly idealistic, dangerously revolutionary, foolishly gullible or what have you.'

The morale is - everyone admonishes a flame, but nothing else gathers posts quite like it. If you think something is terrible, holding back will get you nowhere.