Hacker News new | past | comments | ask | show | jobs | submit | more frogcoder's comments login

Just curious, what are the advantages using w3m instead of eww?


One example: When I open this page here, in eww all comments have the same left margin and I have no idea what is a reply to what, but with emacs-w3m the nesting structure is visible.


Strange, I'm trying out standalone w3m right now and also don't get nesting. Maybe the emacs version is different. I'm guessing HN must indent with CSS (which w3m pointed out it does not attempt to support) even though the comments are in a table.


Actually, HN indents with a spacer gif, in true early 00's fashion :)

  <img src="s.gif" height="1" width="66">


hah, I love it.


I am kind of glad there are so many folks on hacker news using Firefox.

I "fixed" it by refreshing Firefox. You can refresh Firefox from [Help] menu item, and choose [Trouble shooting Mode...]


All features and principles aside, it's a different code base. A mono culture is dangerous for the system, remember heartbleed?


Are the families, friends and supporters of Snowden constantly harassed or threatened by the US government?


I know the project is probably for some fun. Since you already have a sample lisp code to test, why not write tests for it.


Are you suggesting click-bait headlines are equivalent to out right disinformation?


Certainly not "equivalent", but they are indeed a form of disinformation.


I used to love ORM, I used it everywhere. Writing another language in the language I am coding is wrong. ORM simplifies my programs.

No, ORM does not simplify coding! It's a big complex adapter which does not fit many cases.

RDBM itself is complex enough, let's put another complex abstraction above it so we can forget about the tables and columns and joins and foreign keys. Complexity added upon another complexity does not make a polished interface.

If you want to use ORM, you have to learn both SQL and ORM with some depth at least. When problems occur, you have to debug both.

20 years in, I am still learning about RDBM. I still hate to compose SQL in code, but there is no better way.

Databases are used in every situation. Want to store data? Database. Want to communicate between processes? Database. Want to store logs? Database. There are different solutions for different scenarios, but as long as the DB chugs along, why? Sometimes it's sickening.

So 20 years in, the ROI of learning SQL is great. Please don't avoid learning about RDBM by using an ORM. Just learn it.

Actually, I'm not without ORM now a days. Light-weight ORM like Dapper serves well, it does not abstract out the concepts of RDBM, but make things easier.


> Writing another language in the language I am coding is wrong

That's not what's wrong. But rather writing in some language within a string literal is what feels wrong to you.

With better integration it'd be natural. The problem is, of course, there's no single SQL dialect.


" I still hate to compose SQL in code, but there is no better way."

The one big problem with SQL is intermixing query language and query parameters. This requires escaping and is the source of many PHP vulnerabilities. Instead of

    do_sql('SELECT * FROM tab WHERE name = "abc"')
there should have been a standard where you wrote

    do_sql('SELECT * FROM tab where name = V1", "abc")
or something like that. So you don't do string operations on the query parameters.


Aren’t you referring to parameterized/prepared queries? Any proper DB driver/library should have this feature.

    do_sql('SELECT * FROM tab where name = ?", "abc")
https://www.php.net/manual/en/pdo.prepared-statements.php

I recall getting curious when I was younger where the deranged advice of “sanitize your queries” came from — realizing that you should be able to simply tell the database that this is a string, not part of the query itself. SQL injection should barely exist as a concept, let alone be the #1 web vulnerability.

IIRC it turned out MySQL supported parameterized queries for ages, but the stdlib php MySQL library just didn’t add support for it. This discovery solidified my understanding that PHP has been giving developers brain damage for decades.


Unless you're using hardcoded values, using bind variables is the only proper way. Otherwise, the DBMS has difficulty recognizing the same query pattern for performance, and you're open to injection vulnerabilities for security.

https://www.databasestar.com/sql-bind-variables/

The big problem is the shitty workplace environment of today that discourages sharing, learning and proper software development.

A proper build-pipeline will include security scanners that detects these vulnerabilities automagically.


I don't know if it's a standard but both Postgres and MySQL have PREPARE statements, and any sane language driver will implement it correctly


If you use IntelliJ IDE in their commercial version (at least of PyCharm) they integrated DataGrip. Basically if you connect to your database and give an option to fetch your schema the IDE starts scanning for strings and if it detects SQL it provides IDE features to it as well (like auto completion, and some refactoring etc).

I think ORM and query builders were trying to hack around to make IDEs understand SQL, when in reality this approach is what actually was needed.


No, ORM provides an inspectable central entry point for your models with a standardized API. That's the feature.

That's why you get a great django ecosystem: the ORM abstractions allow all libs to rely on the fact the rest of the code access the model the same way.


The issue is that if you try to squeeze a relational model into object oriented model you won't get an efficient solution.

Solutions like django might be good when you're starting the project or it is something very simple, otherwise you'll have to fight with it to get something done more efficiently.

My point is that using plain SQL (I personally prefer asyncpg as it provides interface matching postgresql) is actually also easy. Especially if you have IDE that supports it.

I also realized that with this approach I rarely need to even transform the data in any way. Usually whatever I want to do I can get in a single SQL statement (even for things that have some hierarchy, thanks to aggregation functionality). So in the end the function just gets data and displays it.


Sure if you don't need to build an ecosystem, don't need introspection and can forgo integration, sql is indeed easy.

Also, SQLA proves that an ORM doesn't have to prevent you from getting an efficient solution, you just have to offer several layers of granularity.

Eventually, it's not an or proposition. In django you do use raw sql when you need so. but your auth system doesn't, and a plugin will solve it for you.


One nifty use-case for ORMs is decoupling the logic from the data.

I can prototype in Python/SQLAlchemy/SQLite and deploy to Python/SQLalchemy/PostGreSQL via a pipeline with confidence that I'm actually managing the complexity.

Cracking open some legacy code with vast swaths of embedded SQL is a source of much weeping and gnashing of teeth when the time comes for maintenance.


I did this for the longest time, testing with SQLite and running with PostgreSQL, until I discovered that this was completely unnecessary extra complexity. It turns out that setting up and starting a fresh PostgreSQL database takes about one second, so it's just as easy to just spawn a Postgres for the unit tests. And now I get to enjoy some immensely useful Postgres-specific SQL syntax like "FOR UPDATE SKIP LOCKED".


> Writing another language in the language I am coding is wrong.

Yeah but you're writing your strings in english anyway.


With the introduction of M1, it's hard to find any use of paper magazines these days.


If I wait long enough, maybe I can sell my collection of 90s Wired for more than that stupid Mario 64 cart ;D


I strongly think Python should have more functional programming support. Functional Programming Languages are usually scary to look at for many programmers. Python would not only be a good FP introduction to them, it would also benefit greatly.

Years ago I found out the Guido wouldn't let tail recursion included, and even tried to remove map function from built in functions. Therefore I got the impression that python wouldn't have further support in FP. I really wish that is not the case. With the coming pattern matching in 3.10, My hope is high again.

I have very high respect for Guido van Rossum, I'm not here to discredit him. He's one of the authors in PEP 634.

I wish python would have simpler syntax for lambda which is currently using the lambda expression, even JS is doing better on this. A built-in syntax for partial would also be great. It could be even better if we can have function composition.

Some problems are better solved the FP way. It could even make the program more readable which is one of the strengths of Python.


Yes, coming back to Python after many years with Kotlin and Elm, I see how the Python language guides people to write code in a more unreadable way.

Mutations everywhere. But mainly because mapping and flatting stuff is so burdensome. And it lacking many fp functions and a proper way to call them ergonomically makes a crazy list comprehension the goto tool, which often is much less explicit about what's going on than calling a function with a named and widely understood concept.


> And it lacking many fp functions and a proper way to call them ergonomically makes a crazy list comprehension the goto tool, which often is much less explicit about what's going on than calling a function with a named and widely understood concept.

I've said roughly this before somewhere on HN but cannot find it right now: list comprehensions are like regexes. Below a certain point in complexity, they're a much cleaner and immediately-graspable way of expressing what's going on in a given piece of code. Past that point, they rapidly become far worse than the alternative.

For example, "{func(y): y for x, y in somedict.items() if filterfunc(x)}" is clearer than the equivalent loop-with-tempvars, and significantly clearer than "dict(map(lambda k: (func(somedict[k]), somedict[k]), filter(filterfunc, somedict.keys()))))". Even with some better mapping utilities (something like "mapkeys" or "filtervalues", or a mapping utility for dictionaries that inferred keys-vs-values based on the arity of map functions), I think the "more functional" version remains the least easily intelligible.

However, once you cross into nested or simultaneous comprehensions, you really need to stop, drop, and bust out some loops, named functions, and maybe a comment or two. So too with regex! Think about the regex "^prefix[.](\S+) [1-7]suffix$"; writing the equivalent stack of splits and conditionals would be more confusing and easier to screw up than using the regex; below a point of complexity it's a much clearer and better tool to slice up strings. Past a point regexes, too, break down (for me that point is roughly "the regex doesn't fit on a line" or "it has lookaround expressions", but others may have different standards here).


The annoying thing is they have a performance cost though: list comprehensions can be very fast because they stay in the C codepath of Python, whereas unrolled into a loop you lose some of that.


They added "pattern matching" as a statement.

The irrational hatred of FP is still there, to the point of the absurdity of implementing a hobbled procedural version of pattern matching!

It is bordering on insane.


Please suggest a pattern matching expression syntax that doesn’t require completely changing how the language works.

Pattern matching took so long because it was extremely hard to find that compromise, and I actually think they did an okay job. No, it won’t cover every case, but it will also cover the important ones.


  x = match y:
    case 0: "zero"
    case 1: "one"
    case x:
      y = f(x)
      y+y
  
  print(x)
it can require semicolons or parentheses or even braces somewhere if that's necessary to make the grammar work, idc. just don't make me type out `x = ...` a hundred times...

(yes, i know you could use the walrus operator in the third case)

(also, if anyone wants to reply with "use a named function because READABILITY", please save it)


Judging by the votes you got, your proposal is not well-liked.

In general, breaking Python's syntax rules to introduce block expressions or what you want to call it seems like a steep price to pay for what amounts to syntactic sugar in the end.

However, your proposal actually misses the mark in the same way as the actual match/case does as well. What would be /really/ handy in Python is something like

    {'some_key': bind_value_to_this_name} = a_mapping
because it is so common, especially if you're consuming a JSON API. You of course see the myriad problems with the above.

I think you should read the PEPs on match/case, these things have actually been considered. One idea was to introduce a keyword to say which variables are inputs and which are outputs, but that also violates the general grammar in a way that isn't very nice.

The accepted solution has warts, I agree, but at some point you just have to accept that you can't reach some perfect solution.


> Judging by the votes you got, your proposal is not well-liked.

i'm at peace with that :) [1]

> In general, breaking Python's syntax rules to introduce block expressions or what you want to call it seems like a steep price to pay for what amounts to syntactic sugar in the end.

that's your opinion, i disagree! i think Python would be a better, more pleasant to use language if they figured this out. a girl can dream, ok?

> What would be /really/ handy in Python is something like

  {'some_key': bind_value_to_this_name} = a_mapping
yes, extending the destructuring syntax would be nice, i agree! but the original question was "Please suggest a pattern matching expression syntax [...]", and the post you were responding to was specifically talking about `match`'s syntax. [2]

> I think you should read the PEPs on match/case

i read them when they came out. i'm assuming you're referring to this section from PEP 622:

> "In most other languages pattern matching is represented by an expression, not statement. But making it an expression would be inconsistent with other syntactic choices in Python."

https://www.python.org/dev/peps/pep-0622/#id77

i believe Python's statement-orientatation kinda sucks, so to me this is just "things aren't great, let's stay consistent with that". yeah, yeah, "use a different language if you don't like it" etc.

---

[1] well, maybe not quite, after all i'm here arguing about it.

[2] `match` uses patterns like the one you described in `case` arms, but is distinct from them. i don't see why dict-destructuring syntax couldn't be added in a separate PEP.


pedantic addendum:

looks like i messed up my PEPs -- i linked to PEP622, which was superseded by PEP635 [1]. the gist of it hasn't changed though.

---

[1] https://www.python.org/dev/peps/pep-0635/#the-match-statemen..., Ctrl+F "Statement vs. Expression"


I'm interested in similar proposals that can provide the basis of some common syntax that could be transpiled to other functional programming languages https://github.com/adsharma/py2many

I'm less interested in the syntax (will take anything accepted by a modified ast module), more in the semantics.

Here's a syntax I played with in the past:

  def area(s: Shape):
    pmatch(s):
        Circle(c):
            pi * c.r * c.r
        Rectangle(w, h):
            w * h
    ;;

  def times10(i):
    x = pmatch(i):
        1:
            10
        2:
            20
    ;;
    return x
Two notes:

  * Had to be pmatch, since match is more likely to run into namespace collision with existing code.
  * The delimiter `;;` at the end was necessary to avoid ambiguity in the grammar for the old parser. Perhaps things are different with the new PEG parser.
Code is on my github.


Here is pattern matching as a library that is not built using statements,

https://github.com/santinic/pampy

Clearly it's possible. It's also more ergonomic than PEP 622.


Interesting idea, though falls short of FP matching again. The syntax we actually have does a lot more.


Learn You a Haskell for Great Good taught me list comprehension, and I was surprised to see such a pithy shorthand available in Python (+ dict comprehension). That's a very functional way to transform objects from one shape to another with an in-line expression, no lambda keyword there.

But even the lambda keyword isn't so bad, you can create a dictionary of expressions to call by name, a lot more compact them declaring them the usual way imo: https://github.com/jazzyjackson/py-validate/blob/master/pyva...

To your point, I only recently learned there's a Map function in Python, while in JS I'm .map(x=>y).filter(x=>y).reduce(x=>y)ing left and right.


Yes! List/Dictionary/Generator comprehension is one big plus for Python, it probably came from the functional world. I use it whenever I can.

> But even the lambda keyword isn't so bad, you can create a dictionary of expressions to call by name, a lot more compact them declaring them the usual way imo: https://github.com/jazzyjackson/py-validate/blob/master/pyva...

lambda keyword is better than nothing, it definitely can be improved. Just imaging using javascript syntax in your example.

> To your point, I only recently learned there's a Map function in Python, while in JS I'm .map(x=>y).filter(x=>y).reduce(x=>y)ing left and right.

I think with the introduction of list comprehension Guido saw map function was no longer needed, that was why he wanted it removed. I don't deny it, but using map and filter sometimes are just easier to read. Say [foo(v) for v in a] vs map(foo, a).


Yes but map in Python is riduclously slow when map is combined with a lambda [1]

[1]: https://stackoverflow.com/questions/1247486/list-comprehensi...


It's a bit hard to find recent numbers in that decade-old thread, but the relevant, more up to date, evidence I see (in this answer) says that map is not much slower than a list comprehension: https://stackoverflow.com/a/57104206


I agree.

One gripe that I have with functions like map is that it returns a generator, so you have to be careful when reusing results. I fell into this trap a few times.

I'd also like a simpler syntax for closures, it would make writing embedded DSLs less cumbersome.


> One gripe that I have with functions like map is that it returns a generator, so you have to be careful when reusing results

I hope that is never changed; I often write code in which the map function's results are very large, and keeping those around by default would cause serious memory consumption even when I am mapping over a sequence (rather than another generator).

Instead, I'd advocate the opposite extreme: Python makes it a little too easy to make sequences/vectors (with comprehensions); I wish generators were the default in more cases, and that it was harder to accidentally reify things into a list/tuple/whatever.

I think that if the only comprehension syntax available was the one that created a generator--"(_ for _ in _)"--and you always had to explicitly reify it by calling list(genexp) or tuple(genexp) if you wanted a sequence, then the conventions in the Python ecosystem would be much more laziness-oriented and more predictable memory-consumption wise.

Ah well, water under the bridge, I know.


Personally, I mostly just avoid using map/filter and use a list/generator/set/dict comprehension as required. I don't find map(foo, bar) much easier to read than [foo(thingamajig) for thingamajig in bar]


Yes, this is I think why Guido wanted to get rid of map() syntax - he prefers comprehension syntax.


Simply wrap it in list(), or use a list comprehension. Most things in python3 are iterators now, so the same thing applies to many things.


i think thats the most powerful part of the tool. being able to effortlessly write lazy generators is absolutely amazing when working with any sort of I/O system or async code.


> It could be even better if we can have function composition.

I think composition and piping are such basic programming tools that make a lot of code much cleaner. It's a shame they're not built-in in Python.

So, shameless plug, in the spirit of functools and itertools I made the pipetools library [0]. On top of forward-composition and piping it also enables more concise lambda expressions (e.g. X + 1) and more powerful partial application.

[0] https://0101.github.io/pipetools/doc/


Aren't you contradicting yourself a bit?

First you claim functional languages are scary to look at, then say that you want Python to become more like functional languages. But maybe the reason Python is elegant and easier to read is exactly because Guido had the self-constraint to not go full functional. You also miss the part of the story where he actually did remove `reduce` from builtin, exactly because of how unreadable and confusing it is to most.

It's exactly that kind of decision making I expected from a BDFL, and I think Guido did a great job while he was one keeping Python from going down such paths.


Well, the BDFL is probably the only dictator we all love.

Any decision he made is infinitely more than I could. Because I am just a python user, and an outsider in any decision making process. So for me, he's right all the time. That's a perfect definition of a dictator :)

But I do have wishes. It's like I love my parents but I do want to stay up late sometimes.

Yeah, I totally missed the part he removed reduce from builtin. Sorry about my memory. map, filter, or reduce, it does not matter. As I stated, some problems are better solved functional way. Because Python is such a friendly language, if it includes functional paradigm properly, it would make the functional part more readable than other functional languages.

FP is scary not because it has evil syntax to keep people at distance, it's just an alien paradigm to many. Lot's of non functional languages has functional support, which doesn't make them less readable. E.g. C#, JS. I suspect these languages have helped many understanding FP more. Python could make the jump by including more FP, but not turning into a full-fledged FP.

BTW. I'm still glad reduce is kept in functools.


> Because Python is such a friendly language, if it includes functional paradigm properly, it would make the functional part more readable than other functional languages.

I guess my argument is that Python is friendly exactly because it uses FP paradigms sparingly and conscientiously. Some paradigms such as map and filter can definitely make your code cleaner, while others (such as reduce) only lead to headaches. That being said as you mention we are getting pattern matching, I'm curious to see how that ends up.

i would argue that C# and JS do also use it sparingly and don't go too hard, but also that Python is generally a cleaner language than those. It's hard to know how much of it can be attributed to what, but generally, it's not a trivial thing to predict what impacts a given language feature will have on the readability of the code. A given FP paradigm might be cool in isolation, but when stacked with 4 other ones, it can quickly lead to gibberish code.


After giving some more thought on it. I just realized it was python got me into FP. Although the majority my projects are in C#, Linq never had me interested in FP.

You are right, C# and JS use FP sparingly. I think I expect more from Python because I enjoy writing in Python and my functional adventures were rooted in Python.

Personally, lambda expression is painful to look at. Many times I have deliberately avoided it. It's possible to make improvements, but it seems the FP part just stagnated. Looking forward to pattern matching though.


I was going to say something to that effect.

Functional programming is kind of cool unless it's someone else's code and you need to debug it.


I'd much rather debug someone's pure functional code rather than trying to figure out how someone's imperative code got into some unexpected/invalid state.


Site is down. I believe this is the same article by the author.

https://towardsdatascience.com/functools-the-power-of-higher...


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

Search: