Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Your thoughts / experiences with golang?
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Gentoo Chat
View previous topic :: View next topic  
Author Message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Wed May 03, 2023 7:52 pm    Post subject: Your thoughts / experiences with golang? Reply with quote

A while back I had reviewed a guide to it's usage. It seemed fairly thorough and included at least several things I have no experience with (goroutines, channels, probably one or more other things I'm not recalling).

More recently I happened to watch a video about something related to coreboot. Anyway, the speaker made a tangential comment that they had replaced shell scripts with Go programs.

I finally decided to try it out, and it is one of the most frustrating computing experiences I've ever had.

I suppose I should mention that today's pairing is extra sharp cheddar.

In no particular order:
  • Documentation seems poor, although maybe that's only in comparison to Ptyhon? I don't enjoy Python, but it mostly isn't frustrating.
  • Some naming seems questionable. 'errors.Is' is what comes to mind because it was the most recent, but there were some others.
  • It complains about everything with no "I'm working on it, don't fail" option.
    • Unused import? Fail. Yeah, I commented out the 1 (so far) usage.
    • I get a function working and save it's result to a variable. Except I'm not yet doing anything else with that variable, so... Fail. _ := var seems like an awful workaround.
    • Automatic type conversion. Strings to numbers, I understand. But that it won't even allow int_var * float_var seems ridiculous. Yes, I've read an explanation. Sure, fail with 'go build ...' or at least provide a 'go warn-only ...' option.
  • Ugly syntax: if _, err := ...; err == nil {. Although in Overview there's an example where they may discourage that usage. It isn't clear if that's only for error handling or in general. It seems a fairly common style. The ugly extends to anything involving mixed numerical types as the code (can) become littered with int(float_var) or float64(int_var).
It seems like I've forgot something, but those have certainly been the most frustrating.

I rewrote the equivalent program in Python with slightly more functionality and a lot less frustration (although both are still incomplete.) I resumed working on the Go version to implement some of what I'd done in the Python version, and that's when I experienced the forced type conversion issue.

Summarizing the type conversions: get data from file, convert it to an integer (I suppose starting with float would save a step), evaluate result and possibly change (non-integer) and if changed, write the integer back to the file. The way I was writing to a file I think required using a string, so another conversion. Maybe that conversion is unnecessary, except as I'm trying to learn the language, I'm using the "make it work" approach.

Maybe if I were a better programmer that would be easier, but yikes. I can't say I'd recommend Go at this point.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
spica
Guru
Guru


Joined: 04 Jun 2021
Posts: 339

PostPosted: Wed May 03, 2023 11:30 pm    Post subject: Reply with quote

First steps in a new language can make a first opinion which actually is a look through a prism of prior experience with other languages and expectations of something familiar or similar like in other known languages.
Everything is relative. I've seen Python code which had more PEP484-like hints than actual business logic, and that PEP484-like annotated code was quite hard to maintain; go code looks much easier to understand in this case.
I used golang to write microservices for ecommerce, some data processing tools which required huge amount of memory, plus a few tools to help with maintaining my CI pipeline.
Type conversion is made under the hood if struct tags are used. Of course, data model must be well designed prior writing other code.

Regarding rewriting shell scripts in golang... the interesting question is why they do not rewrite in rust
Back to top
View user's profile Send private message
miket
Guru
Guru


Joined: 28 Apr 2007
Posts: 498
Location: Gainesville, FL, USA

PostPosted: Thu May 04, 2023 5:13 am    Post subject: Re: Your thoughts / experiences with golang? Reply with quote

pjp wrote:
A while back I had reviewed a guide to it's usage. It seemed fairly thorough and included at least several things I have no experience with (goroutines, channels, probably one or more other things I'm not recalling).
I use Go a good bit yet use those concurrency primitives rather sparingly.

pjp wrote:
In no particular order:
  • Documentation seems poor, although maybe that's only in comparison to Ptyhon? I don't enjoy Python, but it mostly isn't frustrating.
I stay away from Python; I'm sure that if I were to try to do much in it that I have learning-curve problems with it. Its use of whitespace to express semantics gives me the heeby-jeebies.

pjp wrote:
  • Some naming seems questionable. 'errors.Is' is what comes to mind because it was the most recent, but there were some others.
The errors token states a namespace. As to the identifier Is in that namespace, there had to be a choice between the simple one-word name or being awfully wordy: errors.IsMatchingError. One fortunate consequence of the use of the package name in the compound identifier is that it gives you a quick clue as to where to find the documentation for it.

pjp wrote:
  • It complains about everything with no "I'm working on it, don't fail" option.
    • Unused import? Fail. Yeah, I commented out the 1 (so far) usage.
I get bitten by this thing often enough, but I keep recalling the reason they implemented this: it holds down on the accumulation of useless cruft. On balance, I'm happy Go does this--several times the error has clued me in that I forgot something.

pjp wrote:
    • I get a function working and save it's result to a variable. Except I'm not yet doing anything else with that variable, so... Fail. _ := var seems like an awful workaround.
My habit is to align debugging statements on the left margin so that they stand out from the code being debugged. (This is one reason I dislike Python--you can't use that trick with Python.) Those "pointless" assignments get aligned on the left too.

Quote:
    • Automatic type conversion. Strings to numbers, I understand. But that it won't even allow int_var * float_var seems ridiculous. Yes, I've read an explanation. Sure, fail with 'go build ...' or at least provide a 'go warn-only ...' option.
One of the hard lessons we learned from C is that its lax typing discipline can lead to some nasty errors. Forbidding that kind of automatic type coercion is a feature of most of the compiled languages that come to mind. It's one of the chief reasons that I've grown hesitant to use interpreted languages.

pjp wrote:
  • Ugly syntax: if _, err := ...; err == nil {. Although in Overview there's an example where they may discourage that usage. It isn't clear if that's only for error handling or in general. It seems a fairly common style.
Yes, it is a common locution; it's largely a consequence of the major language feature that a function may return a set of multiple values. In pretty much any language, the controlling expression of a conditional statement must result in exactly one boolean rvalue. This syntax allows for a multivalued function to work into a control statement.

Consider that the equivalent to this in C still has a strange appearence:
Code:
if (!(err = some_function(&main_value))) {
but in Go you can't just coerce a null pointer to a logical boolean like you can in C. On the other hand, if a C function needs to return multiple values, you need to pass in pointers to variables.

There is one more useful effect that comes from this Go syntax: any variables with implicit declarations in the control statement are local to the block which the statement controls; they are not visible to the surrounding code.

pjp wrote:
The ugly extends to anything involving mixed numerical types as the code (can) become littered with int(float_var) or float64(int_var).
It seems like I've forgot something, but those have certainly been the most frustrating.
When a lot of explicit type casts start showing up, it's time to ask yourself if you're doing things the right way.

pjp wrote:
Summarizing the type conversions: get data from file, convert it to an integer (I suppose starting with float would save a step), evaluate result and possibly change (non-integer) and if changed, write the integer back to the file.
If you are reading data from a text file which someone may have edited by hand, you're up against a parsing problem to ensure you're reading a valid input. If you're working with integers, be sure the text looks like an integer (all digits optionally preceded by a minus sign), then convert it to an integer type. The only reason I'd parse it as a float is if I were expecting a value that could have a decimal fraction or scientific notation and expected to consume a float. This is the kind of checking I do all the time, even when working with Bash scripts.

pjp wrote:
The way I was writing to a file I think required using a string, so another conversion. Maybe that conversion is unnecessary, except as I'm trying to learn the language, I'm using the "make it work" approach.
Fprintf is your friend.

pjp wrote:
Maybe if I were a better programmer that would be easier, but yikes. I can't say I'd recommend Go at this point.
Everything takes practice.

Now having said all this, I point out I still have my quibbles with Go. One that has hit me lately, and where I had a struggle to find a way around the problem, is that Go does not have true mixins/traits. Maybe I could have been more creative with generics, but that evaded me. My problem was that a structure embedded in another structure (thus supplying some methods to satisfy an interface) has no way to be aware of the object in which it is embedded. Another: I wish sometimes that Go had not jettisoned the ternary expression. I also really hate cuddled else's.

On balance, though, I'm happy with the language.

spica wrote:
Regarding rewriting shell scripts in golang... the interesting question is why they do not rewrite in rust
From everything I've seen about Rust, the answer would be that they are not masochists.
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Thu May 04, 2023 8:46 pm    Post subject: Reply with quote

spica wrote:
First steps in a new language can make a first opinion which actually is a look through a prism of prior experience with other languages and expectations of something familiar or similar like in other known languages.
That is a good point. I've dabbled in several, but I'm not a developer (although I'm working on a rather "big" first real program -- not the Go program mentioned in my first post).

I've done exercises and trivial programs with C. I did a bit with Racket and SICP, but that book was a bit much... didn't get far because I was trying to solve math problems more than programming problems. A little Lisp and Erlang. I had similar issues with Erlang in that documentation wasn't great (for my knowledge / experience level) and I couldn't find any examples to make sense of the documentation. I had a better experience with Ruby, but it too had some limitations regarding documentation / examples. I'm generally okay with searching for "how do I do that" if I have something to go on; either clear documentation with their own examples, or examples from elsewhere. Neither Erlang nor Ruby seemed to have much in broad support for getting stat information from files. I couldn't determine if that was my limitation, or a limitation of the language / libraries. That's probably the biggest advantage I've seen with Python. I've tried to get away from it, but as happened with Corleone, just when I thought I was out, it pulled me back in!

spica wrote:
Everything is relative. I've seen Python code which had more PEP484-like hints than actual business logic, and that PEP484-like annotated code was quite hard to maintain; go code looks much easier to understand in this case.
I've only just glanced at that, so I don't have a complete understanding of what that is. However, trying to "bolt on" types in some way seems problematic. Hopefully I don't need to go that deep with Python.

spica wrote:
I used golang to write microservices for ecommerce, some data processing tools which required huge amount of memory, plus a few tools to help with maintaining my CI pipeline.
I don't doubt it's capabilities. That's the main reason I finally decided to try a basic but useful program. Well, that and i was curious about how it might work as a replacement for shell scripts. I would like to stop using those for much other than "one-liners" or very basic, short scripts.

spica wrote:
Type conversion is made under the hood if struct tags are used. Of course, data model must be well designed prior writing other code.
Interesting. I'll take a look. I was reviewing the code and looking for ways to clean it up... the idea of using a struct or similar came to mind, but not for the type conversion issue.

spica wrote:
Regarding rewriting shell scripts in golang... the interesting question is why they do not rewrite in rust
:)

Maybe they since have. It was from 2018:
"I stopped writing bash scripts years ago. I just write Go programs. It's actually easier and more reliable."
https://youtu.be/iffTJ1vPCSo?t=1597

I thought he had also mentioned using Rust for other parts, but I didn't catch that while looking for the Go reference. It was probably a different talk I watched around the same time.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Thu May 04, 2023 9:39 pm    Post subject: Re: Your thoughts / experiences with golang? Reply with quote

miket wrote:
I use Go a good bit yet use those concurrency primitives rather sparingly.
It was mainly a "sound interesting, how does that work, and where/why would you use it" interest.

miket wrote:
I stay away from Python; I'm sure that if I were to try to do much in it that I have learning-curve problems with it. Its use of whitespace to express semantics gives me the heeby-jeebies.
I'm not fond of the significance of whitespace either. If I don't know how to do something, I'm fine with accepting the time to learn what I need to do. I differentiate that from the walls that are put up that block my way and require me to deal with the language first rather than getting some basics working. I think they went too far with some of the choices that fail immediately.

miket wrote:
One fortunate consequence of the use of the package name in the compound identifier is that it gives you a quick clue as to where to find the documentation for it.
I was probably already fairly annoyed by that point so it seemed more significant than it really is. Nonetheless, it still reads poorly. It happened to be the recent example at the time.

miket wrote:
I get bitten by this thing often enough, but I keep recalling the reason they implemented this: it holds down on the accumulation of useless cruft. On balance, I'm happy Go does this--several times the error has clued me in that I forgot something.
I can logically understand the choice. But I lack the experience to find value in it while trying to learn the language. This is where I think some sort of --warn-only mode could go a long way. The latest is how main() doesn't take arguments or return values. I obviously don't know how Go wants that handled, but I can say that I'd like it to be less novel. I just want to exit 1 for an error, I don't really want to see "exit stat 1" from os.Exit(). But I digress.

miket wrote:
My habit is to align debugging statements on the left margin so that they stand out from the code being debugged. (This is one reason I dislike Python--you can't use that trick with Python.) Those "pointless" assignments get aligned on the left too.
If I'm intentionally using something for debugging, I'll try that method. But I still have to run the program to get the error to then go back to the code and add the throw-away statement to silence what IMO shouldn't be a critical failure. It very much interrupts flow and progress for zero benefit in that moment. A warning would be superb for those instances.

miket wrote:
One of the hard lessons we learned from C is that its lax typing discipline can lead to some nasty errors. Forbidding that kind of automatic type coercion is a feature of most of the compiled languages that come to mind. It's one of the chief reasons that I've grown hesitant to use interpreted languages.
I'd guess this is also primarily an issue with my lack of experience. I'm not saying the conversion should be silent, but it would be nice to be less ugly (or again, provide a warning if chosen). I'll obviously get used to it or use something else. I suspect part of the problem is that Go sort of seems like a dynamic language in other ways -- := -- but really isn't. That said, defaulting to float result when encountering integer and float operations also seems reasonable and "safe."

miket wrote:
Consider that the equivalent to this in C still has a strange appearence:
Code:
if (!(err = some_function(&main_value))) {
but in Go you can't just coerce a null pointer to a logical boolean like you can in C. On the other hand, if a C function needs to return multiple values, you need to pass in pointers to variables.
I've worked with pointers, but only in trivial examples. My main surprise was that in creating a new language to address some of the issues with C, "this" is what they thought was a good solution :) I'm surprised that "better readability" wasn't a higher priority. Then again, that may be my lack of experience showing.

miket wrote:
When a lot of explicit type casts start showing up, it's time to ask yourself if you're doing things the right way.
I absolutely did ask that, though I haven't yet answered it. However, in dealing with integers and fractions at the same time, at some point, conversion happens. Arbitrarily: invalid operation: pi * n (mismatched types float64 and int). If the source is an integer and the operation involves a float with the result expected to be an integer, that seems like a lot of conversion that could have been solved by defaulting to float values when a float value was one of the operands. Unfortunately, that's not what they chose. I might have an extraneous operation here or there, but I don't think I will remove too many. I'll try to remember to count when I look to clean up those bits of code. I'll take a look at that tonight.

miket wrote:
If you are reading data from a text file which someone may have edited by hand, you're up against a parsing problem to ensure you're reading a valid input. If you're working with integers, be sure the text looks like an integer (all digits optionally preceded by a minus sign), then convert it to an integer type. The only reason I'd parse it as a float is if I were expecting a value that could have a decimal fraction or scientific notation and expected to consume a float. This is the kind of checking I do all the time, even when working with Bash scripts.
The source and result are integers. For now I just presume the data is an integer and return it from a function as such. I then manipulate it as needed when performing float based computation. The least painful way to write it back to the file seemed to be converting it to a string with Sprintf and WriteString. For now, there is a panic if the data retrieved from the file can't be converted to an integer. I'll eventually modify that to fail more gracefully.

miket wrote:
Fprintf is your friend.
Since I wrote that, I found Sprintf. I'll look at Fprintf, thanks!

miket wrote:
Everything takes practice.
Absolutely. And I very much try to keep in mind that it's the first time I'm doing anything with the language. I didn't even bother with "Hello World". But it isn't that complicated.

miket wrote:
Now having said all this, I point out I still have my quibbles with Go. One that has hit me lately, and where I had a struggle to find a way around the problem, is that Go does not have true mixins/traits. Maybe I could have been more creative with generics, but that evaded me. My problem was that a structure embedded in another structure (thus supplying some methods to satisfy an interface) has no way to be aware of the object in which it is embedded. Another: I wish sometimes that Go had not jettisoned the ternary expression. I also really hate cuddled else's.

On balance, though, I'm happy with the language.
I mainly needed to vent, but partly because I was surprised by multiple choices they made even if I do understand the reasoning. I'll be curious to finish this program and see about rewriting portions my first real "big" project in Go. That will eventually be some sort of file manager / duplicate file management tool. I haven't even looked into what I'll do for a UI. That will probably convert me or make me run away :)
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
flexibeast
Guru
Guru


Joined: 04 Apr 2022
Posts: 479
Location: Naarm/Melbourne, Australia

PostPosted: Fri May 05, 2023 4:28 am    Post subject: Reply with quote

pjp, you might be interested in the following, if you're not already aware of them:

Regarding the unused variables issue, this also happens in Zig, and there's ongoing unhappiness about it, e.g. this and this.
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Fri May 05, 2023 5:37 am    Post subject: Re: Your thoughts / experiences with golang? Reply with quote

pjp wrote:
I'll take a look at that tonight.
This was regarding my use of casting int and floats. I didn't have that many, it just felt like a lot at the time. Most were in print statements to verify I was getting correct results. I also changed the initial read from file to convert to a float so from there on, all work was with floats until it needed to be an integer again.

The next "What?" moment is with exiting. It seems Go insists on exiting with a message. And it's supposed to be script related solution? That is, "os.Exit(1)" produces: "exit status 1". No thanks. Just exit with the error code as normal (or allow it).


@flexibeast:

I'll take a look :). Apparently I had visited the first link, but I don't recognize the content. I considered Zig, but it seems I ought to focus on potentially marketable languages, even if it likely won't matter. One can dream.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
pa4wdh
l33t
l33t


Joined: 16 Dec 2005
Posts: 900

PostPosted: Fri May 05, 2023 8:15 am    Post subject: Reply with quote

I do have quite some programming experience, but not with go, so i'll just share my thoughts :)

Personally, i'll never even attempt to write anything in go and avoid anything written in it.
Go is made by google, and in my book google equals evil. It would be way to easy to hide google spyware in a compiled program without the end user noticing, and with google's business model of grabbing as much of your data as possible i see that as a very big risk i'm not willing to take.
Why would i trust a programming language made by a marketing firm?
_________________
The gentoo way of bringing peace to the world:
USE="-war" emerge --newuse @world

My shared code repository: https://code.pa4wdh.nl.eu.org
Music, Free as in Freedom: https://www.jamendo.com
Back to top
View user's profile Send private message
uid
n00b
n00b


Joined: 05 May 2023
Posts: 1

PostPosted: Fri May 05, 2023 10:08 am    Post subject: Reply with quote

To me Go is best thing since sliced bread.

The compilation errors for unused imports/variables was frustrating in the beginning, but I have since come to love that feature - it forces me to keep my code tidy, and in my experience it catches a bunch of mistakes early in process. It has saved me from a lot of headache.
In general I love that it is a compiled language, since the compiler acts like a first line of defense against bugs - and the compiler is so fast that it runs close to instantly.

Gofmt is another cool feature. Just hit save and your code is formatted properly. No need to manually align, and carefully position each character.

The concurrency features are superb as well. It allows you to structure the code in very simple and interesting ways. Like have a job producer, a channel(queue), and some workers that take from the channel - and express that very clearly in the code. It is just neat. Want to run something in its own "thread" (goroutine) write: go myFunction()

The standard libraries have a great bunch of functionality and you can write web-services with no extra dependencies (I do use 3rd party libraries though). A full production ready file-server is only a few lines of code.
The way the package import work where you specify git repos is also super cool.

The mostly statically linked nature of the compiled binaries, makes app distribution easy as well. No need to install Go or any other dependencies on the target system in order to run it. It is very convenient when distributing programs to many computers (granted, since we are Gentoo users, we may not put so much significance to this ;-)).

So many things about the language make it seem simple and straightforward to understand. The readability of Go is amazing in my opinion.
And I have never had more fun making programs, since becoming relatively fluent in Go.

The only thing that I miss in Go is enums. I do not understand why it doesn't have proper enums. But I just work around that.

It is also possible to make GUI programs with Go. The Fyne framework is really good and worth checking out. They do use CGo for the OpenGL bindings though.

For truly excellent Go learning videos, I highly recommend Matt KøDVB's Go Class: https://youtu.be/iDQAZEJK8lI
It is a high quality video course, that go from simple stuff to advanced Go usage.

In fact, I like Go so much that I do not really want to write in another language. I guess that could be considered a drawback :-)
Back to top
View user's profile Send private message
miket
Guru
Guru


Joined: 28 Apr 2007
Posts: 498
Location: Gainesville, FL, USA

PostPosted: Fri May 05, 2023 1:20 pm    Post subject: Re: Your thoughts / experiences with golang? Reply with quote

pjp wrote:
miket wrote:
I use Go a good bit yet use those concurrency primitives rather sparingly.
It was mainly a "sound interesting, how does that work, and where/why would you use it" interest.
I do have an example in a program I wrote. The problem it solves is fairly involved but doesn't lend itself to parallelism, yet at the very last stage of its operation a goroutine and a channel are vital components. The program generates a tarball using the archive.tar package of the Go standard library. The program can pipe the output of the tar writer through any of gzip, bzip2, or xz in order to compress the tarball. The hangup comes when using xz, which uses considerably more time than the other two. The tar writer would finish and the program would exit before xz could finish. This would cause xz to exit early due to sigpipe and leave a broken tarfile. The solution is to run the compressor from a goroutine and pass the error object via a channel when the compressor finishes. The main program doesn't exit until it receives a value over the channel and is able to report any error that came from running the compressor. And I get a nice uncorrupted tarball to boot.

pjp wrote:
miket wrote:
I stay away from Python; I'm sure that if I were to try to do much in it that I have learning-curve problems with it. Its use of whitespace to express semantics gives me the heeby-jeebies.
I'm not fond of the significance of whitespace either. If I don't know how to do something, I'm fine with accepting the time to learn what I need to do. I differentiate that from the walls that are put up that block my way and require me to deal with the language first rather than getting some basics working. I think they went too far with some of the choices that fail immediately.
Every langauge I've ever used had its own quirks; some have bothered me more than others. Ruby, for example, is supposed to be nice and pretty, but the fact that it has the "convenience" that zero-argument functions are called without parentheses makes it very painful to pass a function as a value. Ada has three string types. Perl function definitions do not have formal-argument lists. PHP has an ugly namespace syntax (I like a Slashdot user's comment: "look[s] like Satan's diverticulitis"). Javascript's type system is a dumpster fire. C makes me happy, but it can also take me over a cliff. On balance, I find Go to be pretty nice.

pjp wrote:
miket wrote:
I get bitten by this thing often enough, but I keep recalling the reason they implemented this: it holds down on the accumulation of useless cruft. On balance, I'm happy Go does this--several times the error has clued me in that I forgot something.
I can logically understand the choice. But I lack the experience to find value in it while trying to learn the language. This is where I think some sort of --warn-only mode could go a long way. The latest is how main() doesn't take arguments or return values. I obviously don't know how Go wants that handled, but I can say that I'd like it to be less novel. I just want to exit 1 for an error, I don't really want to see "exit stat 1" from os.Exit(). But I digress.
Actually, this can help you develop a good habit you can use in programming: to be able to think of what you are going to need later in the program from things done earlier in the program. So, for a stupidly simple example: if the goal of your program is print a list of names and phone numbers, you don't need to waste time and memory fetching ZIP codes from the database. The same idea carries forward to the unused-variable problem. Think of why you will need a variable before you bother setting it up. It's a different thing if you know you'll need the value ln the code you've not yet written, but you want to try out the first part of the program to see how things are working before you work on that later part. Why not print out the value to be sure you're setting it correctly? (Since this would be in a debugging statement, I'd put it at the left margin). Bingo! That squashes the unused-variable error.

You took a useful digression. There's no argc and argv for the main() function because Go has a nice package for parsing command arguments, switches and switch parameters. Look to the flag package.

Yes, that goofy message that Go prints for non-zero return codes is pretty jarring, especially for us who value the taciturn nature of Linux commands.

pjp wrote:
miket wrote:
One of the hard lessons we learned from C is that its lax typing discipline can lead to some nasty errors. Forbidding that kind of automatic type coercion is a feature of most of the compiled languages that come to mind. It's one of the chief reasons that I've grown hesitant to use interpreted languages.
I'd guess this is also primarily an issue with my lack of experience. I'm not saying the conversion should be silent, but it would be nice to be less ugly (or again, provide a warning if chosen). I'll obviously get used to it or use something else. I suspect part of the problem is that Go sort of seems like a dynamic language in other ways -- := -- but really isn't. That said, defaulting to float result when encountering integer and float operations also seems reasonable and "safe."
There are various ways this would not be safe, especially in the light of the fact Go lets you use implicit type definitions (so does C# by means of the var keyword and Rust with the let keyword--to cite two languages where I have zero experience). If you had in mind that the variable would hold an integer but instead ended up as a float, you'd have to be careful of how you do comparisons. You can test two integers for equality without fear, but two floating-point values can be close to equal but not exactly so. You could also end up slowing the program and having it take more working memory if you accidentally used floats instead of integers. The program could also spend a lot of time just converting between integer and float when it really shouldn't have to.

pjp wrote:
miket wrote:
Consider that the equivalent to this in C still has a strange appearence:
Code:
if (!(err = some_function(&main_value))) {
but in Go you can't just coerce a null pointer to a logical boolean like you can in C. On the other hand, if a C function needs to return multiple values, you need to pass in pointers to variables.
I've worked with pointers, but only in trivial examples. My main surprise was that in creating a new language to address some of the issues with C, "this" is what they thought was a good solution :) I'm surprised that "better readability" wasn't a higher priority. Then again, that may be my lack of experience showing.
About the type rules and pointers and coercion: a lot of languages are really tough about pointer treatment. Pascal was a shock to me after having begun with the very tolerant PL/1; you can see all that toughness in all the languages it influenced (including Go). This oddness you see in the Go conditional-statement syntax arises as a workaround for the capability of functions to return multiple results, itself a feature which improves readablity.

To go back to your original example
Code:
// rather than
if _, err := ...; err == nil {

// you can write things on two lines
_, err := ...
if err == nil {
I typically use the latter form. (Though it must be said that the convention is that the branch should handle the error case rather than the non-error case.)

pjp wrote:
miket wrote:
When a lot of explicit type casts start showing up, it's time to ask yourself if you're doing things the right way.
I absolutely did ask that, though I haven't yet answered it. However, in dealing with integers and fractions at the same time, at some point, conversion happens. Arbitrarily: invalid operation: pi * n (mismatched types float64 and int). If the source is an integer and the operation involves a float with the result expected to be an integer, that seems like a lot of conversion that could have been solved by defaulting to float values when a float value was one of the operands. Unfortunately, that's not what they chose. I might have an extraneous operation here or there, but I don't think I will remove too many. I'll try to remember to count when I look to clean up those bits of code. I'll take a look at that tonight.
pjp wrote:
miket wrote:
If you are reading data from a text file which someone may have edited by hand, you're up against a parsing problem to ensure you're reading a valid input. If you're working with integers, be sure the text looks like an integer (all digits optionally preceded by a minus sign), then convert it to an integer type. The only reason I'd parse it as a float is if I were expecting a value that could have a decimal fraction or scientific notation and expected to consume a float. This is the kind of checking I do all the time, even when working with Bash scripts.
The source and result are integers. For now I just presume the data is an integer and return it from a function as such. I then manipulate it as needed when performing float based computation. The least painful way to write it back to the file seemed to be converting it to a string with Sprintf and WriteString. For now, there is a panic if the data retrieved from the file can't be converted to an integer. I'll eventually modify that to fail more gracefully.
If you're overflowing a 64-bit integer (wow!), do be aware that you are at risk of overflowing the mantissa of a floating-point value. You'd print a value that could look like an integer but with a loss of precision; the result would no longer be exact. Go has an arbitrary-precision math package, math.big. You might look there. My bet, though, is that something else is going awry in your approach to the problem.

pjp wrote:
miket wrote:
Everything takes practice.
Absolutely. And I very much try to keep in mind that it's the first time I'm doing anything with the language. I didn't even bother with "Hello World". But it isn't that complicated.
Indeed! Jumping in with a real problem to solve is my typical approach to a new language. One thing I do do a lot when I'm trying to work out what the language would do in a particular case is to write a short program on the side to try it out as an isolated example. I did the very thing when I wrote my first message in this thread to confirm what I recalled about C's type coercion around ints and floats:
Code:
#include <stdio.h>

int main(int argc, char **argv) {
    int a = 3;
    float b = 4.0;
    printf("value: %f\n", a * b);
    return 0;
}


pjp wrote:
miket wrote:
Now having said all this, I point out I still have my quibbles with Go. One that has hit me lately, and where I had a struggle to find a way around the problem, is that Go does not have true mixins/traits. Maybe I could have been more creative with generics, but that evaded me. My problem was that a structure embedded in another structure (thus supplying some methods to satisfy an interface) has no way to be aware of the object in which it is embedded. Another: I wish sometimes that Go had not jettisoned the ternary expression. I also really hate cuddled else's.

On balance, though, I'm happy with the language.
I mainly needed to vent, but partly because I was surprised by multiple choices they made even if I do understand the reasoning. I'll be curious to finish this program and see about rewriting portions my first real "big" project in Go. That will eventually be some sort of file manager / duplicate file management tool. I haven't even looked into what I'll do for a UI. That will probably convert me or make me run away :)
Since I'm a command-line guy and do a good bit of network programming, I hit a Go sweet spot. GUI programming is a whole different matter. Unless your GUI is in a web browser, you have to use some third-party package to get you there. There are several of those, including a couple that ease that GUI-in-a-browser trick. I haven't tried any of them, so I can't offer a recommendation.
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Sat May 06, 2023 5:26 am    Post subject: Reply with quote

flexibeast wrote:
pjp, you might be interested in the following, if you're not already aware of them:

I read most of the first one and skimmed the other two. They at least seem to have consistent complaints. However, I note that two of them admitted to using Rust. That isn't specifically a problem, but seems to be an instance of the pot calling the kettle black.

From the first article, a couple of things stood out. First:
Quote:
It doesn't take much skill to notice a problem.

In fact, as developers get more and more senior, they tend to ignore more and more problems, because they've gotten so used to it. That's the way it's always been done, and they've learned to live with them, so they've stopped questioning it any more.

Junior developers however, get to look at everything again with a fresh pair of eyes: they haven't learned to ignore all the quirks yet, so it feels uncomfortable to them, and they tend to question it (if they're made to feel safe enough to voice their concerns).
Then this:
emphasis as quoted wrote:
The success of Rust is due in large part to it being easy to adopt piecemeal and playing nice with others.
Shortly thereafter:
Quote:
Rust cryptography code has found its way into Python, [...]


I wonder if this is the same code that resulted in architecture / portability problems. I didn't follow that "conflict" closely, but at least initially that didn't seem to exhibit "playing nice with others." Nevertheless, I may still try implementing the program in Rust. It would probably give me enough of a feel for whether or not I thought it was worth pursuing in the short term.

I have already experienced multiple things the articles mention, so there is that :).

Regarding the Zig links, I agree with the concept of failing "for release, not prototyping."
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Sat May 06, 2023 5:28 am    Post subject: Reply with quote

pa4wdh wrote:
I do have quite some programming experience, but not with go, so i'll just share my thoughts :)
I understand and sympathize with your concerns. I happened to have a real example to use as a test and so I did. I was curious what Thompson and Pike* would have come up with to solve some of the negatives with other languages (* I know there was a third, but I'm not familiar with his other work). So far, I'm quite surprised, and refer back to my last post. Ultimately it's just a tool and I was curious.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Sat May 06, 2023 5:49 am    Post subject: Reply with quote

uid wrote:
The compilation errors for unused imports/variables was frustrating in the beginning, but I have since come to love that feature - it forces me to keep my code tidy, and in my experience it catches a bunch of mistakes early in process. It has saved me from a lot of headache.
In general I love that it is a compiled language, since the compiler acts like a first line of defense against bugs - and the compiler is so fast that it runs close to instantly.

Gofmt is another cool feature. Just hit save and your code is formatted properly. No need to manually align, and carefully position each character.
I'm still early for it to be helpful, and so far the it has only caused headaches :) That it is a compiled language appealed to me as well. Using it as a replacement for scripts seemed to be a common usage for it, so it seemed like a possibly ideal solution. So far I haven't used gofmt. Maybe it isn't picky, or vim handles that automatically, or I naturally write in gofmt style, or ...

uid wrote:
The concurrency features are superb as well. It allows you to structure the code in very simple and interesting ways. Like have a job producer, a channel(queue), and some workers that take from the channel - and express that very clearly in the code. It is just neat. Want to run something in its own "thread" (goroutine) write: go myFunction()

The standard libraries have a great bunch of functionality and you can write web-services with no extra dependencies (I do use 3rd party libraries though). A full production ready file-server is only a few lines of code.
I like that those features are part of the language. I don't have any experience with concurrency, but am considering using a web interface for my "duplicate file management" tool. Having those features in a single language seemed like a possible advantage.

uid wrote:
The way the package import work where you specify git repos is also super cool.
This is one of the "features" of modern programming that I find off-putting. There's been at least a couple of prominent incidents where that caused a problem in production. For prototyping, maybe it's fine. But for security, it seems to fail the Confidentiality, Integrity and Availability triad.

uid wrote:
The mostly statically linked nature of the compiled binaries, makes app distribution easy as well. No need to install Go or any other dependencies on the target system in order to run it. It is very convenient when distributing programs to many computers (granted, since we are Gentoo users, we may not put so much significance to this ;-)).
That too was a feature I found appealing. I've come to have a strong dislike for dynamic language version churn. It seems almost intended to create busy work. Something that's stable isn't bad because it's github page shows there have been no updates in the last 100 milliseconds.

uid wrote:
So many things about the language make it seem simple and straightforward to understand. The readability of Go is amazing in my opinion.
And I have never had more fun making programs, since becoming relatively fluent in Go.

The only thing that I miss in Go is enums. I do not understand why it doesn't have proper enums. But I just work around that.

It is also possible to make GUI programs with Go. The Fyne framework is really good and worth checking out. They do use CGo for the OpenGL bindings though.

For truly excellent Go learning videos, I highly recommend Matt KøDVB's Go Class: https://youtu.be/iDQAZEJK8lI
It is a high quality video course, that go from simple stuff to advanced Go usage.

In fact, I like Go so much that I do not really want to write in another language. I guess that could be considered a drawback :-)
Thanks for the enthusiasm, encouragement, and references!

I'm trying to narrow down the pool of options. C or some hybrid of C/C++ (with as little of the ++ as possible, although I don't know exactly what that looks like yet); Python (until something can displace it -- maybe Go?); and until something better comes along, possibly PHP (or Python or Go?) and some Javascript. That's still a lot. Only time will tell.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Sat May 06, 2023 6:16 am    Post subject: Reply with quote

miket wrote:
I do have an example in a program I wrote. The problem it solves is fairly involved but doesn't lend itself to parallelism, yet at the very last stage of its operation a goroutine and a channel are vital components. The program generates a tarball using the archive.tar package of the Go standard library. The program can pipe the output of the tar writer through any of gzip, bzip2, or xz in order to compress the tarball. The hangup comes when using xz, which uses considerably more time than the other two. The tar writer would finish and the program would exit before xz could finish. This would cause xz to exit early due to sigpipe and leave a broken tarfile. The solution is to run the compressor from a goroutine and pass the error object via a channel when the compressor finishes. The main program doesn't exit until it receives a value over the channel and is able to report any error that came from running the compressor. And I get a nice uncorrupted tarball to boot.
Interesting. One feature of my duplicate files manager would include a means to consolidate files from different paths into a new path. Using a tar file was my first thought as a way to solve that. Maybe I'll try that as my next Go task -- without parallelism! :)

miket wrote:
Actually, this can help you develop a good habit you can use in programming: to be able to think of what you are going to need later in the program from things done earlier in the program. So, for a stupidly simple example: if the goal of your program is print a list of names and phone numbers, you don't need to waste time and memory fetching ZIP codes from the database. The same idea carries forward to the unused-variable problem. Think of why you will need a variable before you bother setting it up. It's a different thing if you know you'll need the value ln the code you've not yet written, but you want to try out the first part of the program to see how things are working before you work on that later part. Why not print out the value to be sure you're setting it correctly? (Since this would be in a debugging statement, I'd put it at the left margin). Bingo! That squashes the unused-variable error.

You took a useful digression. There's no argc and argv for the main() function because Go has a nice package for parsing command arguments, switches and switch parameters. Look to the flag package.
I use an iterative approach because I haven't yet internalized general solutions. For simple things, I'll incorporate them directly into the program. For something particularly new or that I suspect requires me to focus on the specificity of the task, I'll create something in it's own program, then incorporate it into the larger program.

To be specific, the program I'm working on is a replacement for the deprecated xbacklight. I knew I'd need command line arguments, so that was the second task after getting a basic, do-nothing program. And as seems consistent with my experience with Go so far, the flag package seems quirky :). After that, I looked at how to read data from a file, then how to write it back. More or less anyway.

So my unused variable was retrieving the current brightness from a file and returning it so I could then calculate the requested change. I was checking that I hadn't made any notable mistakes when Go complained about the unused variable. My main issue about it being a fatal error is that it takes me out of the flow of thought to address something that could easily have been a warning.

That disruptive nature is so far a big enough frustration that it remains to be seen if I get used to it. If not for those, the float/int conversions would have probably bothered me less, but the cumulative effect was greater than the sum of it's parts. I'm sure I had a thought along the lines of "Does everything have to be a fight?"

miket wrote:
Yes, that goofy message that Go prints for non-zero return codes is pretty jarring, especially for us who value the taciturn nature of Linux commands.
As small as that is, it was a notable reaction along the lines "is that really how they exit programs intended for use on the command line?" I had envisioned using Go along side shell scripts, awk, grep or whatever. It really seems like an odd "feature." For now my xbacklight program simply returns from functions in such a way that it exits without an error, though I do provide a message about what went wrong, the return code is always 0. I haven't looked for any common solutions for how to address that.

miket wrote:
There are various ways this would not be safe
That's why I put safe in quotes. In my case, I knew what I was working with and just wanted the simple solution that was good enough. As I mentioned in a different reply to the thread, this is one of those fail in release not in prototyping moments. But that's not what it is, so I'll see what happens over time.

Although, even as I write that, I can't say with certainty that when I reviewed the code and cleaned it up to use only floats except where an integer was necessary, that I would have done so without having to use a bunch of float64() and int() conversions. At a minimum, it was a marker for where to look. But then again, 'go prototype' and 'go build' could also address that nicely, and with less disruption.

miket wrote:
About the type rules and pointers and coercion: a lot of languages are really tough about pointer treatment. Pascal was a shock to me after having begun with the very tolerant PL/1; you can see all that toughness in all the languages it influenced (including Go). This oddness you see in the Go conditional-statement syntax arises as a workaround for the capability of functions to return multiple results, itself a feature which improves readablity.

I have only vague memories of Pascal from a class in 10th grade. And while I can't be certain, I believe I wondered about how the choice was made to use the term Writeln. The 'ln' seems unnecessary and without benefit. More so when there is a formatted version of a command.

miket wrote:
I typically use the latter form. (Though it must be said that the convention is that the branch should handle the error case rather than the non-error case.)
I believe I had seen some examples that didn't involve error handling. The error handling example was one I knew I could find. In the end, it isn't that big of a deal, it just doesn't seem readable for uses that aren't as simple. I believe most languages support writing code that scores low on readability. That form happened to catch my attention.

miket wrote:
If you're overflowing a 64-bit integer (wow!), do be aware that you are at risk of overflowing the mantissa of a floating-point value. You'd print a value that could look like an integer but with a loss of precision; the result would no longer be exact. Go has an arbitrary-precision math package, math.big. You might look there. My bet, though, is that something else is going awry in your approach to the problem.
The issue was mainly putting int()'s and float64()'s to make it work. As I believe I've mentioned, I cleaned that up. When reading data from the file, I convert the integer to a float and return that. The remainder of the code then works solely with float values until the new integer is to be written back to the file. In that sense, I can see that the requirement to use the conversions did help when rewriting. When I used grep to find the float64 uses, most of them were in debug print statements. Without them, obviously there wouldn't have been anything to search for, so that's useful too.

miket wrote:
One thing I do do a lot when I'm trying to work out what the language would do in a particular case is to write a short program on the side to try it out as an isolated example.
If it wasn't clear, that's what I was describing in my "iterative" approach. At least for me, isolating the problem seems to go a long way toward clarifying what needs to be done as opposed to trying to make it fit into a particular use case.

[quote="miket"]Since I'm a command-line guy and do a good bit of network programming, I hit a Go sweet spot. GUI programming is a whole different matter. Unless your GUI is in a web browser, you have to use some third-party package to get you there. There are several of those, including a couple that ease that GUI-in-a-browser trick. I haven't tried any of them, so I can't offer a recommendation.[/qutoe] It seems that Go is well suited for networked applications. That was a big part of it's draw in finally trying it.

For now I'm planning on using a web GUI, although I've never used a web application that I thought worked as well compared to native applications. I'm also considering curses or ansi.


As an aside, I briefly tried writing some of the xbacklight program in rust. Only retrieving the value from a file, converting it to a string, then an integer, and then a float where it is returned to perform an arbitrary calculation against a percentage. That was an experience. I'm sure there's a better way than that assembly line of conversions, but that's all I was able to make sense out of. And it took a while to get there. Oh, and rust apparently doesn't have the ability to tell what type a variable is, because "that has to be known at compile time," for whatever that means. I don't know how much more I'll pursue that option since relatively basic stuff seems weirdly complicated.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
Chiitoo
Administrator
Administrator


Joined: 28 Feb 2010
Posts: 2747
Location: Here and Away Again

PostPosted: Sat May 06, 2023 12:52 pm    Post subject: Reply with quote

I tried Go a bit for a job position I was thinking of applying for (maybe I even did), and was quite disappointed to see how it enforces code style.

No "Allman style" allowed! I tend to use that for everything unless it's not just my code, or if it otherwise might inconvenience.

That is enough for me to not want to learn more of it, though I guess I could do something like this:

Code:

blah {
        ye
     }

But yeah... meh.
_________________
Kindest of regardses.
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Sun May 07, 2023 11:30 pm    Post subject: Reply with quote

For functions, I've been preferring Allman(?):
Code:
foo()
{
    ...
}
And for non-function blocks:
Code:
bar {
    ...
}
Although the latter is probably due to my laptop display.


I did a brief example of creating a tar file with Go and Python, and Go and I aren't meshing yet. Some of that is familiarity, but documentation isn't helping me get over that hill.

This is a lot more useful and helpful to me:
https://docs.python.org/3/library/tarfile.html

Than this:
https://pkg.go.dev/archive/tar@go1.20.4

The line count for my Go version is 62 lines without comments compared with Python at 17 lines (with one comment and the #! line). Go has 6 lines for an error handling function and 7 lines related to the tar file header. 1 of those header lines is where I modify the path to change what's in the tar file from the original location. I haven't done that in the Python version. 4 of the header lines seem necessary to build the tar file with file name, size, mode, and modify time. I don't know if those are required, but I'm not compelled to dig in to find out (see documentation).

For now I guess I'll be sticking with Python, but I may mess around with Go if something else comes up where it seems suitable. For my "duplicate files manager" program, using Python for it and Flask for the web stuff may make life easier. I'm still quite a ways from that.

I suppose that's enough procrastinating with Go and xbacklight that I ought to get back to fiddling with python and sqlite.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
Dr.Willy
Guru
Guru


Joined: 15 Jul 2007
Posts: 547
Location: NRW, Germany

PostPosted: Wed May 10, 2023 10:10 pm    Post subject: Reply with quote

miket wrote:
pjp wrote:
  • Ugly syntax: if _, err := ...; err == nil {. Although in Overview there's an example where they may discourage that usage. It isn't clear if that's only for error handling or in general. It seems a fairly common style.
Yes, it is a common locution; it's largely a consequence of the major language feature that a function may return a set of multiple values. In pretty much any language, the controlling expression of a conditional statement must result in exactly one boolean rvalue. […]

That is not at all unique to Go. Just off the top of my head you can do that in javascript, c++, python and rust. Its just that noone outside of Go-land thought that was a sensible way to do error-handling.

pjp wrote:
As an aside, I briefly tried writing some of the xbacklight program in rust. Only retrieving the value from a file, converting it to a string, then an integer, and then a float where it is returned to perform an arbitrary calculation against a percentage. That was an experience. I'm sure there's a better way than that assembly line of conversions, but that's all I was able to make sense out of. And it took a while to get there. Oh, and rust apparently doesn't have the ability to tell what type a variable is, because "that has to be known at compile time," for whatever that means. I don't know how much more I'll pursue that option since relatively basic stuff seems weirdly complicated.

These days I don't think there are many arguments in favour of C/C++ - not when Zig and Rust exist. Now you already had a look at rust and … well, isn't it a glorious combination of complex and pedantic. It has its merits, but they dont seem to be relevant to your usecase.

As for my own opinion on Go, I don't really like it. It has some nice tooling: the go compiler, the runtime, gofmt … but as far as Go the language is concerned I think its garbage. It is full of idiosyncrasies that, to me, seem questionable at best: Like, why is a language designed in the 2000s using nullable pointers? What is all this "make(...)" nonsense? What is this error handling? What are these enums? Isn't 'defer' just a poor man's contextmanager? I heard that Go does support generics now, but … what?! It's like a window into the 1980s in terms of PL design.
_________________
gentoo repos: kakoune | oil | hyper-v
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Thu May 11, 2023 7:36 pm    Post subject: Reply with quote

Dr.Willy wrote:
noone outside of Go-land thought that was a sensible way to do error-handling.
Haha! I wonder how much of the language is the way it is because it's creators had a "rule" that they all had to agree on something before it could become part of the language.

Dr.Willy wrote:
These days I don't think there are many arguments in favour of C/C++ - not when Zig and Rust exist. Now you already had a look at rust and … well, isn't it a glorious combination of complex and pedantic. It has its merits, but they dont seem to be relevant to your usecase.
The problem with Zig would be whether or not it can build significant momentum. Separately I've read it has poor documentation and some other issues I forget. But for now I haven't tried it because of the momentum thing. I'm still deluding myself that maybe I could get a job in the field, so whatever I learn should be reasonably relevant.

My "use case" for Rust was learning it with a small project. So if learning it isn't relevant to my use case, then I guess that leaves me with C.

Not long after I had written about that experience with Rust, I decided to look at some of their learning resources. First was "Rust by Example" which seemed to be aimed at someone who didn't know Rust, but understood the syntax. Maybe most of what they described or use in code is understandable to someone who knows C++, but it obviously wasn't meant for me.

I then tried what I think they referred to as the "Rust Book." I think it was in chapter 2, not long after beginning working with actual code that it wanted me to download something from the internet without any explanation of why I should trust it. And that was to something as basic as a random function. My understanding of their description of the repository is that anyone could upload code to it. That seems more of a security problem than the one the language was created to address. I tried to look at the repository to see if there was an obvious way to determine a "safe" area, perhaps one only associated directly with the language, such as a stdlib or something like that, but nothing rendered on the page without javascript.

Dr.Willy wrote:
As for my own opinion on Go, I don't really like it. It has some nice tooling: the go compiler, the runtime, gofmt … but as far as Go the language is concerned I think its garbage. It is full of idiosyncrasies that, to me, seem questionable at best: Like, why is a language designed in the 2000s using nullable pointers? What is all this "make(...)" nonsense? What is this error handling? What are these enums? Isn't 'defer' just a poor man's contextmanager? I heard that Go does support generics now, but … what?! It's like a window into the 1980s in terms of PL design.
I had similar thoughts, but less specific. I presumed it was due to my lack of knowledge. I might give it another shot if I end up disliking Flask or think of something else to do with it.

On the subject of enums, I tried Python's version. The implementation seems strange, although I suppose it is Pythonic.

"Color = Enum('Color', ['RED', 'GREEN', 'BLUE'])" where RED is 1. But using the class method, RED can be 0. And then Color.RED returning an enum object and having to do Color.RED.value to use it as a "traditional" enum. I have no comment on Go's implementation as I didn't try them.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
Chiitoo
Administrator
Administrator


Joined: 28 Feb 2010
Posts: 2747
Location: Here and Away Again

PostPosted: Thu May 11, 2023 10:24 pm    Post subject: Reply with quote

pjp wrote:
For functions, I've been preferring Allman(?):
Code:
foo()
{
    ...
}
And for non-function blocks:
Code:
bar {
    ...
}
Although the latter is probably due to my laptop display.

Yeah, I mean, sure, "Allman" takes more space but... I tend to use nano a lot for editing and when the braces and paren and curlies get crazy like in JavaScript or rather TypeScript in my current case... it's simply a nightmare to follow who ends and starts where...

I forget how bad Go is in that regard, but yeah, it's just so much easier to see them when they are aligned, with or without a fancy IDE (which have their own problems too... ugh, despite having a cost of xxx on their get).

I've been playing around a bit with Nix and NixOS as of late, too, due to reasons, and the brace/paren/curlies issue is getting to me there, too. Kind of makes me want to curl up like a C Python and Bash on something...
_________________
Kindest of regardses.
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Fri May 12, 2023 12:25 am    Post subject: Reply with quote

Chiitoo wrote:
Yeah, I mean, sure, "Allman" takes more space but... I tend to use nano a lot for editing and when the braces and paren and curlies get crazy like in JavaScript or rather TypeScript in my current case... it's simply a nightmare to follow who ends and starts where...
If I ever move back to a desk with a real monitor, I'd probably stick with Allman, but if it gets crazy, I have to wonder if maybe there needs to be some editing. For similar readability reasons, I'm not a fan of lambda functions.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
Dr.Willy
Guru
Guru


Joined: 15 Jul 2007
Posts: 547
Location: NRW, Germany

PostPosted: Sun May 14, 2023 7:11 pm    Post subject: Reply with quote

pjp wrote:
On the subject of enums, I tried Python's version. The implementation seems strange, although I suppose it is Pythonic.

Strange is … generous. It is a bolted-on addition in pythons stdlib and looks pretty much like Go's or C's.

If you wanna know what an enum should be capable of, have a look at Rust's enums

Chiitoo wrote:
I've been playing around a bit with Nix and NixOS as of late, too, due to reasons, and the brace/paren/curlies issue is getting to me there, too. Kind of makes me want to curl up like a C Python and Bash on something...

Excuse me, sir, do you have a moment to talk about Guix? :P
_________________
gentoo repos: kakoune | oil | hyper-v
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20580

PostPosted: Sun May 14, 2023 8:09 pm    Post subject: Reply with quote

Dr.Willy wrote:
pjp wrote:
On the subject of enums, I tried Python's version. The implementation seems strange, although I suppose it is Pythonic.

Strange is … generous. It is a bolted-on addition in pythons stdlib and looks pretty much like Go's or C's.

If you wanna know what an enum should be capable of, have a look at Rust's enums
I thought Python's looked very different from C, but I've not used it much in C (anywhere really). Unfortunately I don't have the experience to understand the advantage of whatever Rust is providing there.
_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
Chiitoo
Administrator
Administrator


Joined: 28 Feb 2010
Posts: 2747
Location: Here and Away Again

PostPosted: Mon May 15, 2023 12:24 pm    Post subject: Reply with quote

Dr.Willy wrote:
Chiitoo wrote:
I've been playing around a bit with Nix and NixOS as of late, too, due to reasons, and the brace/paren/curlies issue is getting to me there, too. Kind of makes me want to curl up like a C Python and Bash on something...

Excuse me, sir, do you have a moment to talk about Guix? :P

Heh, I did not remember that being a thing.

Might need to give it some time at some point as well... thanks!
_________________
Kindest of regardses.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Gentoo Chat All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum