Live data from Hacker News

Learning Go as a Python Developer: The Good and the Bad

new.pythonforengineers.com

251–260 of 269 posts

Re: Learning Go as a Python Developer: The Good and the Bad

#251

I don't think Python packaging is as bad as people make out (if packages only stick to the basic features of Python!) A far bigger issue I see is despite Python supposedly being 'cross-platform': the language introduces so many small, backwards-compatibility breaking changes that you really need to use the most up to date interpreter you can. For instance: there is now a really cool operator that lets you do expressi…

Python 3.8 and its walrus operator is 2.5 years old, it's not bleeding edge, at least not anymore. That being said, I'm worried about the language in that complexity increases through the introduction of new language features without much benefit at all.

2.5 years is still bleeding edge for a backwards-incompatible syntax change.

Re: Learning Go as a Python Developer: The Good and the Bad

#252
post #69

Earlier quoted context omitted.

The __init__.py is also itself a module, which you import by importing the package. That's confusing, and not easily avoided!

Make it an empty file?

"Just make an empty file there" is the opposite of a solution to it being confusing!

Re: Learning Go as a Python Developer: The Good and the Bad

#253
post #219

Earlier quoted context omitted.

Yes. In elixir, you can install GPU stuff (Nx) with very few problems. Some people have built some really cool tools like burrito, which cross-compile and bundles up the VMs to other architectures . Even before that it's been pretty common to cross-compile from x86 to an arm raspberry pi image in the form of Nerves. As a rule elixir devs don't do system level dependencies, probably because of lessons learned from the…

Ok, now I am curious :) let's try some typical problems from the Python package ecosystem: - Can you resolve precompiled GPU dependencies with system managed CUDA driver versions? - Are there packages that can convert PDF to PNG without system dependencies? - Can you run a Qt GUI app on CI without needing to do any additional system setup? With regards to cross compilation tools like burrito, that's neat! But Python…

1) not sure how Nx does it.

2) not that I can find for that specific task but the typical strategy is to download (or compile) a binary, drop it into a {project-dependency}[0]-local "private assets" directory, and call out the binary. This is for example how I embed zig pl into elixir (see "zigler") without system-level dependencies. Setting this up is about 40 lines of code.

3) wx is preferred in the ecosystem over qt, but this (and openssl) are the two biggies in terms of "needs system deps", though it's possible to run without wx.

For native graphics, elixir is treading towards glfw, which doesn't have widgets, but from what I hear there are very few if any gotchas in terms of using it.

I bring up cross-compilation, because burrito allows you to cross-compile natively implemented code, e.g. bcrypt that's in a library. So libraries that need c-FFI typically don't ship binaries, they compile at build time. Burrito binds "the correct" architecture into the c-flags and enables you to cross compile c-FFI stuff, so you don't have a system level dependency.

[0] not that this has happened, but two dependencies in the same project could download different versions of the same binary and not collide with each other.

Re: Learning Go as a Python Developer: The Good and the Bad

#254
post #60
post #50

Earlier quoted context omitted.

But poetry requires pip… you can't use it without using pip

Poetry requires pip in the way that `go mod` requires `go get`, i.e. Poetry allows one to operate at a higher level of abstraction, where it's harder to make mistakes and generally easier to manage your dependency tree.

Abstractions are amazing until they break and you have to fix them.

Re: Learning Go as a Python Developer: The Good and the Bad

#255
post #185
post #184

Earlier quoted context omitted.

This really isn't a good argument though: it's an extra, extremely specific use case for assignment that looks visually very similar. And worse, effects code maintainability - if you need that assignment higher up, you're now editing the if statement, adding an assignment, plus whatever your interstitial code is. Python doesn't have block scoping so the argument for it is weak.

It's not for extremely specific use-case, unless you consider using variables as a condition of an if statement or loop extremely specific. > And worse, effects code maintainability - if you need that assignment higher up, you're now editing the if statement, adding an assignment, plus whatever your interstitial code is. How is that different than variables declared without the walrus operator? If you declare a varia…

So by way of example - suppose I have this:

  # some other code
  
  if determined_value := some_function_call():
      do_action(determined_value)
  
and then I change it to this:

  # some other code
  
  determined_value = some_function_call()
  logger.info("Determined value was %s", determined_value)
  validate(determined_value)
  
  if determined_value:
      do_action(determined_value)
  
and determined_value is a reasonably expensive operation (at the very least I would never want to redundantly do it twice) - then in this case my diff for this looks like:

  --- 
  +++ 
  @@ -1,5 +1,8 @@
  -
   # some other code
   
  -if determined_value := some_function_call():
  +determined_value = some_function_call()
  +logger.info("Determined value was %s", determined_value)
  +validate(determined_value)
  +
  +if determined_value:
       do_action(determined_value)
whereas if I wrote it without walrus originally:

  --- 
  +++ 
  @@ -1,5 +1,8 @@
   # some other code
   
   determined_value = some_function_call()
  +logger.info("Determined value was %s", determined_value)
  +validate(determined_value)
  +
   if determined_value:
       do_action(determined_value)
  
then the diff is easier to read, and the intent is clearer because diff can simply infer that what's happening is the semantic addition of two lines.

Code is read more then it's written, and changed more then originally created, and making the change case clearer makes sense.

Re: Learning Go as a Python Developer: The Good and the Bad

#256
post #254
post #60

Earlier quoted context omitted.

Poetry requires pip in the way that `go mod` requires `go get`, i.e. Poetry allows one to operate at a higher level of abstraction, where it's harder to make mistakes and generally easier to manage your dependency tree.

Abstractions are amazing until they break and you have to fix them.

Sure, this is true for every abstraction: some are more air-tight or leaky than others, but IME Poetry and go mod are fairly solid.

I haven’t had to use pip in a long time. Just like I haven’t had to use `go get` in a while.

I mean it’s not the most rock solid abstraction, but introducing sane package management in an OSS environment with a decade plus of history is very hard. Against that background, they are doing pretty well, IMO.

Re: Learning Go as a Python Developer: The Good and the Bad

#257
post #255
post #185

Earlier quoted context omitted.

It's not for extremely specific use-case, unless you consider using variables as a condition of an if statement or loop extremely specific. > And worse, effects code maintainability - if you need that assignment higher up, you're now editing the if statement, adding an assignment, plus whatever your interstitial code is. How is that different than variables declared without the walrus operator? If you declare a varia…

So by way of example - suppose I have this: # some other code if determined_value := some_function_call(): do_action(determined_value) and then I change it to this: # some other code determined_value = some_function_call() logger.info("Determined value was %s", determined_value) validate(determined_value) if determined_value: do_action(determined_value) and determined_value is a reasonably expensive operation (at the…

Your issue is with the readability of the diff? That is so trivial. You're trying to find anything to complain about at this point. How about just look at the code? You should be doing that anyway.

Re: Learning Go as a Python Developer: The Good and the Bad

#258
post #257
post #255

Earlier quoted context omitted.

So by way of example - suppose I have this: # some other code if determined_value := some_function_call(): do_action(determined_value) and then I change it to this: # some other code determined_value = some_function_call() logger.info("Determined value was %s", determined_value) validate(determined_value) if determined_value: do_action(determined_value) and determined_value is a reasonably expensive operation (at the…

Your issue is with the readability of the diff? That is so trivial. You're trying to find anything to complain about at this point. How about just look at the code? You should be doing that anyway.

Diffs are the predominant way people relate to code changes via PRs. It is standard practice to restructure patch sets to produce a set of easy to read to changes which explain what is happening - what "was" and what "will be".

Re: Learning Go as a Python Developer: The Good and the Bad

#259
post #258
post #257

Earlier quoted context omitted.

Your issue is with the readability of the diff? That is so trivial. You're trying to find anything to complain about at this point. How about just look at the code? You should be doing that anyway.

Diffs are the predominant way people relate to code changes via PRs. It is standard practice to restructure patch sets to produce a set of easy to read to changes which explain what is happening - what "was" and what "will be".

It's standard practice to look at the code alongside a diff. Better yet, use your IDE or a tool to show you far more detail than a diff possibly could. https://www.jetbrains.com/help/pycharm/comparing-files-and-f...

This is such a pedantic, non-issue I don't even know why I'm bothering acknowledging it.

Re: Learning Go as a Python Developer: The Good and the Bad

#260
post #214

Earlier quoted context omitted.

>But Python has a decent and a reproducible way of installing packages. Reading the comment thread it's not immediately clear what the answer is - it seems implied that the proper way is using Poetry, is that the case?

It's not. See https://imgs.xkcd.com/comics/python_environment_2x.png Or sometime the computer is haunted and my colleague had problems installing tensorflow. To this day he has no working tensorflow.

I suppose we can follow memes or facts.

Please note I never used tensorflow on that computer in fact I never used tensorflow, but this is my experience: https://gist.github.com/takeda/89ec29501b6e8641415668f22f3e9...

It succeeded after first try.

I do see that in their repo[1] they use a non standard way to build the package. They use Bazel, but that's Google for you. They never do things everyone else is doing. I'm not sure why this is Python problem rather than package problem.

They have tons of open issues around building: [2]

[1] https://github.com/tensorflow/tensorflow

[2] https://github.com/tensorflow/tensorflow/labels/type%3Abuild...

Post reply on HN