[go-nuts] ANN: ficta 1.0.0

2023-05-10 Thread Michael Ellis
I've just released ficta, a small project built using Francisco Escher's 
goopenai package.
https://github.com/Michael-F-Ellis/ficta
Ficta is a command line program that lets you use OpenAI's completion API 
from any text editor.
Ficta exists because I found it frustrating to write short stories and 
essays via the ChatGPT web interface. With ficta, the developing story 
becomes the prompt. ficta also lets you change LLM model and parameters 
freely in mid-stream.


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5cace9f2-4d16-4e72-a3bd-59326209348bn%40googlegroups.com.


Re: [go-nuts] Re: Looking for a specialized proxy package

2023-03-15 Thread Michael Ellis
Thanks, Matthew.  I know what RPC is, but have never considered it as a way 
to serve http from behind a NAT.  I should say that the IOT's are part of a 
product that's been in the market for several years.  My client likes the 
web interface we built and wants users to be able to access an IOT's pages 
through a secure intermediary server.  How would that work with grpc?

On Wednesday, March 15, 2023 at 7:08:04 PM UTC-4 Matthew Zimmerman wrote:

> Honestly I'd probably use grpc and keep a constant connection from the IOT 
> to the cloud.  No ports/services required on the client at all and the 
> server can still request things in real time.
>
> Like: 
> https://www.talentica.com/blogs/part-3-building-a-bidirectional-streaming-grpc-service-using-golang/
>
> On Wed, Mar 15, 2023, 6:35 PM Michael Ellis  wrote:
>
>> FWIW,  I pasted my  post into ChatGPT-4 and got what might be a plausible 
>> outline of an approach using httputil.NewSingleHostReverseProxy.
>>
>> But, as we know, LLM's are prone to hallucination. If you're curious, 
>> here's a share link. 
>>
>> https://shareg.pt/cNoNdWc
>>
>> On Wednesday, March 15, 2023 at 5:57:48 PM UTC-4 Michael Ellis wrote:
>>
>>> I posted a question about this on ServerFault 
>>> <https://serverfault.com/questions/1125770/iot-http-multiplexing-through-cloud-host>last
>>>  
>>> week but didn't get any answers other than a few comments from one person 
>>> who said (basically) "use a VPN".   That seems like overkill.  I'm trying 
>>> to find a reliable way to proxy occasional HTTP access to any of  ~100 
>>> geographically dispersed IOT devices through a cloud server.  
>>>
>>> I'm using Go on the cloud server and on the IOT devices, so I thought 
>>> I'd ask here.
>>>
>>> *Situation:*
>>>
>>>- We have complete control over the configuration of the IOT devices 
>>>and the cloud host.
>>>- We don't have control of the customers' routers and firewalls, but 
>>>can specify minimum requirements for port openings, etc.
>>>- FWIW, the IOT devices are BeagleBone Black running Debian Buster 
>>>and the cloud host will be, typically, a multi-core droplet (or similar) 
>>>running Linux.
>>>- The IOT's serve dynamic web pages over HTTP. (HTTPS doesn't seem 
>>>feasible because of certificate requirements and overall load on the IOT 
>>>cpu.) The cloud host will have HTTPS capability.
>>>- This is a low-traffic situation. The IOT's report some overall 
>>>status information (via rsync/ssh) at 4 minute intervals). We already 
>>> have 
>>>a web interface (written in Go) on the cloud server that aggregates and 
>>>displays the status reports.
>>>- Access to an IOT's web service will only occur when a user wants 
>>>to investigate a problem report in more detail. Typically, only one or 
>>> two 
>>>users will have credentials to browse the cloud server.
>>>
>>> The scheme I have in mind is: 
>>>
>>>1. At configuration time for each IOT device the installation tech 
>>>will use ssh-copy-id to install the IOT device's public key on the cloud 
>>>service.
>>>2. The IOT device will  then remotely execute a one-shot program 
>>>(already written and tested) on the cloud server.  The IOT will provide 
>>> a 
>>>unique identifier as an argument and the program will return a permanent 
>>>port number and add a record to a database to record the assignment.
>>>3. The IOT will open a reverse SSH tunnel on the server (probably 
>>>managed by auto-ssh) specifying the permanent port on the server and a 
>>>local port on which it will listen for HTTP requests.
>>>4. The cloud server, when generating status report pages, will 
>>>include a link to fetch the home page of each IOT device by embedding 
>>> its 
>>>unique identifier specified in step 2 above.
>>>
>>> The piece I'm missing is how to construct a proxying handler that will 
>>> use the identifier in the link to look up the tunnel port and fetch the 
>>> IOT's home page and thereafter make it seem as though the user is directly 
>>> browsing the IOT.
>>>
>>> Any help appreciated (and thanks for reading this far!)
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop 

[go-nuts] Re: Looking for a specialized proxy package

2023-03-15 Thread Michael Ellis
FWIW,  I pasted my  post into ChatGPT-4 and got what might be a plausible 
outline of an approach using httputil.NewSingleHostReverseProxy.

But, as we know, LLM's are prone to hallucination. If you're curious, 
here's a share link. 

https://shareg.pt/cNoNdWc

On Wednesday, March 15, 2023 at 5:57:48 PM UTC-4 Michael Ellis wrote:

> I posted a question about this on ServerFault 
> <https://serverfault.com/questions/1125770/iot-http-multiplexing-through-cloud-host>last
>  
> week but didn't get any answers other than a few comments from one person 
> who said (basically) "use a VPN".   That seems like overkill.  I'm trying 
> to find a reliable way to proxy occasional HTTP access to any of  ~100 
> geographically dispersed IOT devices through a cloud server.  
>
> I'm using Go on the cloud server and on the IOT devices, so I thought I'd 
> ask here.
>
> *Situation:*
>
>- We have complete control over the configuration of the IOT devices 
>and the cloud host.
>- We don't have control of the customers' routers and firewalls, but 
>can specify minimum requirements for port openings, etc.
>- FWIW, the IOT devices are BeagleBone Black running Debian Buster and 
>the cloud host will be, typically, a multi-core droplet (or similar) 
>running Linux.
>- The IOT's serve dynamic web pages over HTTP. (HTTPS doesn't seem 
>feasible because of certificate requirements and overall load on the IOT 
>cpu.) The cloud host will have HTTPS capability.
>- This is a low-traffic situation. The IOT's report some overall 
>status information (via rsync/ssh) at 4 minute intervals). We already have 
>a web interface (written in Go) on the cloud server that aggregates and 
>displays the status reports.
>- Access to an IOT's web service will only occur when a user wants to 
>investigate a problem report in more detail. Typically, only one or two 
>users will have credentials to browse the cloud server.
>
> The scheme I have in mind is: 
>
>1. At configuration time for each IOT device the installation tech 
>will use ssh-copy-id to install the IOT device's public key on the cloud 
>service.
>2. The IOT device will  then remotely execute a one-shot program 
>(already written and tested) on the cloud server.  The IOT will provide a 
>unique identifier as an argument and the program will return a permanent 
>port number and add a record to a database to record the assignment.
>3. The IOT will open a reverse SSH tunnel on the server (probably 
>managed by auto-ssh) specifying the permanent port on the server and a 
>local port on which it will listen for HTTP requests.
>4. The cloud server, when generating status report pages, will include 
>a link to fetch the home page of each IOT device by embedding its unique 
>identifier specified in step 2 above.
>
> The piece I'm missing is how to construct a proxying handler that will use 
> the identifier in the link to look up the tunnel port and fetch the IOT's 
> home page and thereafter make it seem as though the user is directly 
> browsing the IOT.
>
> Any help appreciated (and thanks for reading this far!)
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/4eee9142-17f1-4d78-9057-9702e1d2d557n%40googlegroups.com.


[go-nuts] Looking for a specialized proxy package

2023-03-15 Thread Michael Ellis


I posted a question about this on ServerFault 
last
 
week but didn't get any answers other than a few comments from one person 
who said (basically) "use a VPN".   That seems like overkill.  I'm trying 
to find a reliable way to proxy occasional HTTP access to any of  ~100 
geographically dispersed IOT devices through a cloud server.  

I'm using Go on the cloud server and on the IOT devices, so I thought I'd 
ask here.

*Situation:*

   - We have complete control over the configuration of the IOT devices and 
   the cloud host.
   - We don't have control of the customers' routers and firewalls, but can 
   specify minimum requirements for port openings, etc.
   - FWIW, the IOT devices are BeagleBone Black running Debian Buster and 
   the cloud host will be, typically, a multi-core droplet (or similar) 
   running Linux.
   - The IOT's serve dynamic web pages over HTTP. (HTTPS doesn't seem 
   feasible because of certificate requirements and overall load on the IOT 
   cpu.) The cloud host will have HTTPS capability.
   - This is a low-traffic situation. The IOT's report some overall status 
   information (via rsync/ssh) at 4 minute intervals). We already have a web 
   interface (written in Go) on the cloud server that aggregates and displays 
   the status reports.
   - Access to an IOT's web service will only occur when a user wants to 
   investigate a problem report in more detail. Typically, only one or two 
   users will have credentials to browse the cloud server.

The scheme I have in mind is: 

   1. At configuration time for each IOT device the installation tech will 
   use ssh-copy-id to install the IOT device's public key on the cloud service.
   2. The IOT device will  then remotely execute a one-shot program 
   (already written and tested) on the cloud server.  The IOT will provide a 
   unique identifier as an argument and the program will return a permanent 
   port number and add a record to a database to record the assignment.
   3. The IOT will open a reverse SSH tunnel on the server (probably 
   managed by auto-ssh) specifying the permanent port on the server and a 
   local port on which it will listen for HTTP requests.
   4. The cloud server, when generating status report pages, will include a 
   link to fetch the home page of each IOT device by embedding its unique 
   identifier specified in step 2 above.

The piece I'm missing is how to construct a proxying handler that will use 
the identifier in the link to look up the tunnel port and fetch the IOT's 
home page and thereafter make it seem as though the user is directly 
browsing the IOT.

Any help appreciated (and thanks for reading this far!)

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/116894c3-e90c-4181-9d94-06780724bdf9n%40googlegroups.com.


[go-nuts] Re: Facing issues while using builtin functions while executing golang templates

2022-10-20 Thread Michael Ellis
I did a quick search for "is not a defined function".  That message appears 
once in https://go.dev/src/text/template/exec.go.  It's triggered when 
findFunction() fails while executing a template.

Hope that's of some use.


On Wednesday, October 19, 2022 at 8:20:46 AM UTC-4 rit...@ext.dunzo.in 
wrote:

>
> We are facing a strange issue within one of our services where randomly 
> one of the docker containers in production out of (N,  N>50)  starts 
> randomly failing on an API while trying to execute a golang template with 
> an error *"Err: template: : executing \"\" 
> at len: \"len\" is not a defined function".  *`len` is a builtin function 
> within golang so am stumped why this error comes.  Some more context
>
>
>- *Golang Version: 1.15*
>- The same Pod was serving this API and executing the template 
>correctly before this issue started coming
>- Parsing the template works fine, only executing fails. We are 
>parsing and executing in sequence.
>- After this error was encountered first, all subsequent API calls to 
>the same container failed with the same error
>- The same API on all other containers works perfectly fine.  We 
>removed the container from serving prod traffic, and this issue disappeared
>- This is the second time the issue is happening, first time we 
>restarted the container and hence weren't able to debug much
>-  Binary is stripped of symbol tables and ptrace is not enabled
>
> We have the container running (not serving prod traffic) so if there are 
> any hints on how to debug this issue would appreciate.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5f252adb-4d0c-4d86-bc61-8b3a47be68d9n%40googlegroups.com.


Re: [go-nuts] Generics faster than native float64?

2022-04-19 Thread Michael Ellis
FWIW, no difference on my  MacBook.

(base) michaels-mbp copybench % go test -bench=.
goos: darwin
goarch: amd64
pkg: localgo/copybench
cpu: Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
BenchmarkCopy-8 6999800   169.4 ns/op
BenchmarkCopyG-86967590   170.6 ns/op
PASS
ok  localgo/copybench2.810s

On Tuesday, April 19, 2022 at 11:06:39 AM UTC-4 peterGo wrote:

> As Ian has pointed out, software and hardware optimizations may distort 
> the results of microbenchmarks.
>
> If I run the original benchmarks using go1.18 and go1.19 the Copy and 
> CopyG ns/op results are reversed.
>
> # Original: https://go.dev/play/p/m1ClnbdbdWi
>
> ~/x$ go1.18 version && go1.18 test x_0_test.go -bench=.
> go version go1.18.1 linux/amd64
> BenchmarkCopy-8 3820009310.7 ns/op
> BenchmarkCopyG-87552230158.3 ns/op
>
> ~/x$ go version && go test x_0_test.go -bench=.
> go version devel go1.19-a11a885cb5 Mon Apr 18 23:57:00 2022 + 
> linux/amd64
> BenchmarkCopy-8 7577499158.2 ns/op
> BenchmarkCopyG-83870822309.7 ns/op
>
> If I run the benchmarks with a ResetTimer() using go1.18 and go1.19 the 
> Copy and CopyG ns/op results are effectively the same.
>
> # ResetTimer: https://go.dev/play/p/hansq5ARrSh
>
> ~/x$ go1.18 version && go1.18 test x_1_test.go -bench=.
> go version go1.18.1 linux/amd64
> BenchmarkCopy-8 7581037158.0 ns/op
> BenchmarkCopyG-87590849157.9 ns/op
>
> ~/x$ go version && go test x_1_test.go -bench=.
> go version devel go1.19-a11a885cb5 Mon Apr 18 23:57:00 2022 + 
> linux/amd64
> BenchmarkCopy-8 7525525158.5 ns/op
> BenchmarkCopyG-87521787158.5 ns/op
>
> If I run the original benchmarks on a Celeron N3450 using go1.18 and 
> go1.19 the Copy and CopyG ns/op results are effectively the same. I run 
> benchmarks on a Celeron N3450 because Intel disables many hardware 
> optimizations on cheap hardware.
>  
> # Original: https://go.dev/play/p/m1ClnbdbdWi
>
> $ go1.18 version && go1.18 test x_0_test.go -bench=.
> go version go1.18.1 linux/amd64
> BenchmarkCopy-4 2773934   428.0 ns/op
> BenchmarkCopyG-42783043   429.7 ns/op
>
> $  go version && go test x_0_test.go -bench=.
> go version devel go1.19-a11a885cb5 Mon Apr 18 23:57:00 2022 + 
> linux/amd64
> BenchmarkCopy-4 2781676   428.6 ns/op
> BenchmarkCopyG-42765179   429.0 ns/op
>
>
> Peter
>
> On Tuesday, April 19, 2022 at 12:37:48 AM UTC-4 Ian Lance Taylor wrote:
>
>> On Mon, Apr 18, 2022 at 1:14 PM Feng Tian  wrote: 
>> > 
>> > Hi, I have the following simple benchmark code, 
>> > 
>> > https://go.dev/play/p/m1ClnbdbdWi 
>> > 
>> > I run this on my laptop since Go playground does not run benchmark 
>> code. The strange thing is that Copy of float64 is slower than copy using 
>> generics. I can imagine generics may add no overhead, but how can it be 
>> faster? 
>> > 
>> > ftian@DESKTOP-16FCU43:~/tmp$ go test -bench=. 
>> > goos: linux 
>> > goarch: amd64 
>> > pkg: a 
>> > cpu: 11th Gen Intel(R) Core(TM) i7-11370H @ 3.30GHz 
>> > BenchmarkCopy-8 5693944 221.7 ns/op 
>> > BenchmarkCopyG-8 8885454 137.1 ns/op 
>> > PASS 
>> > ok a 2.838s 
>>
>> The numbers for this kind of micro-benchmark can be deceptive. For 
>> example, they can be highly affected by alignment of the instruction 
>> loop. I don't know exactly what is happening for you. I compiled the 
>> code with "go test -c" and disassembled it: both benchmark functions 
>> contained exactly the same instructions. 
>>
>> Ian 
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7b9ca17c-7c52-480d-9efd-ffec453ab12en%40googlegroups.com.


Re: [go-nuts] encoding/json mistakenly transfer int64 format to string

2022-04-14 Thread Michael Ellis
@Brian
That example is a superbly concise explanation go mod. Thanks! And I had no 
idea you could specify filenames and modules in the Playground.  That's 
really useful!

On Wednesday, April 13, 2022 at 3:11:54 AM UTC-4 Brian Candler wrote:

> > I am a little bewildered by  the new mod configuration.
>
> It's as simple as this:
>
> go mod init blah
> go mod tidy
>
> You can put anything(*) for "blah". Literally "blah" will work. It's just 
> whatever name you want to give your module. However if you plan to publish 
> your module on github then using "github.com/name/project" allows it to 
> be found automatically (**).
>
> "go mod tidy" reads through your source code, finds the imported 
> dependencies, and fetches them for you.  After that, a "go build" or "go 
> run" will work.  If you add or remove dependencies, run "go mod tidy" again.
>
> These commands create "go.mod" and "go.sum" files. They become part of 
> your source code - i.e. you should check them in if you are using a source 
> control system.
>
> If you create additional packages in subdirectories, then those packages 
> are referenced in import statements as /. You only need 
> one go.mod at the top level.
> Example: https://go.dev/play/p/GgHLoOuHtUH
>
> HTH,
>
> Brian.
>
> (*) OK, not quite anything: there are some lexical constraints.
> https://go.dev/ref/mod#go-mod-file-ident
> (**) See
> https://go.dev/ref/mod#module-path
>
> On Wednesday, 13 April 2022 at 07:35:13 UTC+1 yan.z...@gmail.com wrote:
>
>> Thank you Steven. 
>> I am a little bewildered by  the new mod configuration. Will it compile 
>> If I download the source file from the new github source to src directory 
>> without further setting up a mod in the old fashioned way? I am using 
>> go1.15.
>>
>> And today I ran a test logging all the sendings to Redis and readings 
>> from Redis. It is fine - nothing went wrong. But 
>> AnotherRedisDesktopManager still shows the same string format - which I 
>> guess is due to it is 32bit and fail to transfer a long decimal to float32.
>>
>> So nothing is wrong in golang or its open-source package.
>>
>> On Tue, Apr 12, 2022 at 9:56 PM Steven Hartland  
>> wrote:
>>
>>> First off, the package you're using for redis isn't maintained; you 
>>> should switch to github.com/gomodule/redigo/redis instead, which will 
>>> allow you to remove the c == nil check as that doesn't happen.
>>>
>>> In your example you're ignoring error from json.Marshal which could be 
>>> hiding a problem, so I would recommend you handle that.
>>>
>>> encoding/json should represent float as a json number so I would never 
>>> expect what you're seeing but its not clear to me if that is down to how 
>>> you are viewing it.
>>>
>>> On Tue, 12 Apr 2022 at 04:02, Zhaoxun Yan  wrote:
>>>
 The scenario is upon receiving an incoming financial quotation, save it 
 as a string of json into a Redis service. Sorry but I cannot provide the 
 whole code of quotation receiving here, which is very complex with cgo. 
 But 
 the code below will help you get a glimpse on what should be going on:

 import (
 "encoding/json"
 //"errors"
 "fmt"
 "time"
 
 "github.com/garyburd/redigo/redis"
 )

 var pool *redis.Pool

 type Fvprices struct {
 P float64 `json:"price"`
 F float64 `json:"floor"`
 C float64 `json:"ceiling"`
 S float64 `json:"settle"`
 T int64   `json:"time"`
 }

 func init() {
 pool = newPool()
 }

 var redisport = "6379"
 var redisip = "127.0.0.1"
 var password = ""

 func newPool() *redis.Pool {

 fmt.Println("redis @", redisport, redisip, password)
 return { 
 MaxIdle: 4,
 MaxActive:   50, // max number of connections
 IdleTimeout: 30 * time.Second,

 Dial: func() (redis.Conn, error) {
 c, err := redis.DialURL("redis://" + redisip + ":" + 
 redisport)
 if err != nil {
 ErrMsg = fmt.Sprintf("redis connection error: %s", err.
 Error())
 fmt.Println(time.Now().Format("2006-01-02 15:04:05"), 
 ErrMsg)
 return nil, err
 }
 if _, autherr := c.Do("AUTH", password); autherr != nil {
 ErrMsg = fmt.Sprintf("redis password error: %s", err.
 Error())
 fmt.Println(time.Now().Format("2006-01-02 15:04:05"), 
 ErrMsg)
 return nil, autherr
 }
 return c, nil
 },
 }
 }

 func Upfutureprice(future_id string,
 future_price, lowerLimitPrice, upperLimitPrice, preSettlementPrice 
 float64,
 updatetime time.Time) {

 c := pool.Get()
 if c == nil {
 return
 }
 defer c.Close()

 content := Fvprices{

Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis
Thanks, Axel & Robert.  As I said in the first post, the package already 
works well for my purposes (and apparently for the few others who use it).  
It allows defining web content more concisely than raw HTML and makes the 
full power of Go available for composing repetitive page structures.

I was mostly just curious about the possibility of detecting bad content at 
compile time instead of at run time. In practice, that's turned out not to 
be a significant problem so I'm ok with learning generics don't support a 
fix.

On Monday, December 20, 2021 at 2:31:32 PM UTC-5 axel.wa...@googlemail.com 
wrote:

> Oh, forgot the footnote:
>
> [1] Note that even that doesn't *actually* work, as `*HtmlNode` would 
> become a parametric type, so it would have to be instantiated to be used in 
> the constraint - you'd have to write `type HtmlNode[T string | 
> *HtmlNode[Something]]`. And the fact that there is no actual answer to what 
> "Something" would be should be a strong indicator for how much generics are 
> not what you want for this.
>
> On Mon, Dec 20, 2021 at 8:29 PM Axel Wagner  
> wrote:
>
>>
>>
>> On Mon, Dec 20, 2021 at 7:07 PM Michael Ellis  
>> wrote:
>>
>>> >Just to be clear, the way I understood you is that you want HtmlTree.C 
>>> to be a slice which has elements which can each either be a string or an 
>>> *HtmlTree - i.e. you want these to be mixed in a single slice. Correct?
>>>
>>> Actually, no.  An HtmlTree instance whose content is a string is a 
>>> terminal node.  The recursion in the Render() func looks like:
>>>
>>>   for _, c := range h.C {
>>> switch c := c.(type) {
>>> case string:
>>> b.WriteString(c)
>>> case *HtmlTree:
>>> err = Render(c, b, rindent)
>>> if err != nil {
>>> return fmt.Errorf("%s : %v", h.T, err)
>>> }
>>> default:
>>> return fmt.Errorf("Bad content %v. Can't render 
>>> type %T! ", h.C, c)
>>> }
>>> }
>>>
>>
>> That's pretty much what I meant, yes. You want a sum type (and in lieu of 
>> sum types, an interface), not generics. 
>> The "union" aspect of Go generics (the `a | b` syntax) only applies to 
>> using interfaces as *constraints*, not as *types* - you want to do the 
>> latter. You want to have a field which is either a string or an *HtmlNode - 
>> but Go only gives you a convenient way to write the two distinct types 
>> `type HtmlNodeString struct { /*…*/ C string }` and `type HtmlNodeNode 
>> struct { /* … */ C *HtmlNode }` into one¹ type declaration and write 
>> function which can work on either. It's just not what you want.
>>
>> The best option for you is (as Robert mentions) to use an interface, 
>> which is an "open sum" - meaning you can't have the guarantee that its 
>> dynamic type is of a limited set of options, but you *can* have a value 
>> whose actual type is dynamic. You can look at e.g. ast.Node 
>> <https://pkg.go.dev/go/ast#Node>, which is de-facto the same thing - 
>> it's supposed to be a limited set of options, but in lieu of sum types, 
>> it's an interface.
>>
>> Go might, at some point, allow the union-elements of constraint 
>> interfaces to be used as actual types, which *would* be a form of sum 
>> types. But probably not for a while - it's more complicated than it may 
>> seem.
>>
>>
>>>
>>> I suppose it's still a problem, though, since the compiler doesn't have 
>>> any way of knowing that's how trees of HtmlTree meant to be constructed. I 
>>> should have expressed the intended constraint on HtmlTree.C as `string | 
>>> []*HtmlTree`.  Does that make a difference?
>>> On Monday, December 20, 2021 at 10:25:26 AM UTC-5 
>>> axel.wa...@googlemail.com wrote:
>>>
>>>> Just to be clear, the way I understood you is that you want HtmlTree.C 
>>>> to be a slice which has elements which can each either be a string or an 
>>>> *HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
>>>> Because that is not a use case for generics, it's a use case for sum 
>>>> types (which Go does not have).
>>>>
>>>> On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis  
>>>> wrote:
>>>>
>>>>> > They can't, sorry.
>>>&

Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis


On Monday, December 20, 2021 at 1:33:49 PM UTC-5 ren...@ix.netcom.com wrote:

> You should use interfaces and a “node” type.
>

Hmm, I tried 

type Node interface {
string | []*HtmlTree
}

type HtmlTree struct {
T string // html tagname, e.g. 'head'
A string // zero or more html attributes, e.g 'id=1 class="foo"'
C Node   // a slice of content whose elements may be strings or 
*HtmlTree
empty bool   // set to true for empty tags like 
}

and the compiler said: 
./prog.go:21:8: interface contains type constraints.

(line 21 is the declaration of HtmlTree.C as type Node)

What's the syntax you have in mind?


 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c619d54d-5a69-4828-b10b-771722f8f646n%40googlegroups.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis
>Just to be clear, the way I understood you is that you want HtmlTree.C to 
be a slice which has elements which can each either be a string or an 
*HtmlTree - i.e. you want these to be mixed in a single slice. Correct?

Actually, no.  An HtmlTree instance whose content is a string is a terminal 
node.  The recursion in the Render() func looks like:

  for _, c := range h.C {
switch c := c.(type) {
case string:
b.WriteString(c)
case *HtmlTree:
err = Render(c, b, rindent)
if err != nil {
return fmt.Errorf("%s : %v", h.T, err)
}
default:
return fmt.Errorf("Bad content %v. Can't render 
type %T! ", h.C, c)
}
}

I suppose it's still a problem, though, since the compiler doesn't have any 
way of knowing that's how trees of HtmlTree meant to be constructed. I 
should have expressed the intended constraint on HtmlTree.C as `string | 
[]*HtmlTree`.  Does that make a difference?
On Monday, December 20, 2021 at 10:25:26 AM UTC-5 axel.wa...@googlemail.com 
wrote:

> Just to be clear, the way I understood you is that you want HtmlTree.C to 
> be a slice which has elements which can each either be a string or an 
> *HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
> Because that is not a use case for generics, it's a use case for sum types 
> (which Go does not have).
>
> On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis  
> wrote:
>
>> > They can't, sorry.
>> Ok. Thanks, Axel. 
>> Saves me wasting more time.  In the past 3 years of using Go, this is the 
>> only use case where I've  really wanted generics (other cases I've 
>> encountered so far are easily handled with code generation). 
>>
>> -- 
>>
> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>>
> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com?utm_medium=email_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2de22684-0263-465c-8ac0-ff288c535fb7n%40googlegroups.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis
> They can't, sorry.
Ok. Thanks, Axel. 
Saves me wasting more time.  In the past 3 years of using Go, this is the 
only use case where I've  really wanted generics (other cases I've 
encountered so far are easily handled with code generation). 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com.


[go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis
I've got a package, github.com/Michael-F-Ellis/goht, that supports creating 
HTML docs in Go.  It works well, for my purposes at least, but I've always 
been bothered by having to use []interface{} to define the struct member, 
C, that supports recursion.

type HtmlTree struct {
T string// html tagname, e.g. 'head'
A string// zero or more html attributes, e.g 'id=1 
class="foo"'
C []interface{} // a slice of content whose elements may be 
strings or *HtmlTree
empty bool  // set to true for empty tags like 
}

I've created a minimal extract of the package on the playground at 
https://go.dev/play/p/-_7JKRZYLC_J?v=gotip.  Assuming the new generics can 
support constraining HtmlTree.C to be a slice of string | *HtmlTree, what 
is the right syntax for doing so?

Thanks!


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a8817b41-85dd-4fd1-a946-00764713c008n%40googlegroups.com.


[go-nuts] Re: Do you have a minimal runnable go code that contain all key words in go?

2021-12-06 Thread Michael Ellis
Nice! Noticed it didn't have "new" so I changed the counter initializer in 
main() from

var c = counter

to 

p := new(counter)
var c = *p

https://go.dev/play/p/2vw4w44qSWm


On Sunday, December 5, 2021 at 4:10:54 PM UTC-5 ben...@gmail.com wrote:

> Not strictly "minimal" -- it uses some keywords twice, and I'm sure it's 
> longer than it needs to be, but here you go: 
> https://go.dev/play/p/XPoqfI8RmyH
>
> On Monday, December 6, 2021 at 4:54:04 AM UTC+13 cuiw...@gmail.com wrote:
>
>> show me you code
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/851b403a-dc73-487f-b10e-e1608cb8cda2n%40googlegroups.com.


Re: [go-nuts] Which error handling pattern do you prefer?

2021-11-12 Thread Michael Ellis
FWIW (which may not be much) I've settled on explicitly naming my return 
values in the function declaration.  If the function returns include an 
error, I name always name it err. The general pattern is

func foo() (v someType, err error) {
  err = doSomething()
  if err != nil {
err = fmt.Errorf("some context: %v", err)
return
}
  err = doNextThing()
  if err != nil {
 err = fmt.Errorf("some context: %v", err)
 return
  }
// etc
return
}

Naming the error solves the initial := problem.  As for shadowing, I make 
it a point never to do a := assignment involving err. For example, if I 
need to call os.Open, I do

var f *os.File
f, err = os.Open(...)

I tend to use other names for errors only when it's something I can fix 
within the local scope.

At first I tried hard to avoid the verbosity.  Now I use a few helpful 
snippets to reduce keystrokes and an editor plugin the partially fades any 
block that starts with "if err != nil".  The latter works amazingly well 
(for me at least) to reduce visual clutter.  I like it much better than one 
I tried that auto-folds error blocks.  It made me waste time unfolding them 
to see what was inside :-)

YMMV, of course.

On Friday, November 12, 2021 at 11:15:21 AM UTC-5 david@gmail.com wrote:

> On Fri, Nov 12, 2021 at 7:48 AM Miguel Angel Rivera Notararigo <
> ntr...@gmail.com> wrote:
>
>> I tend to use errX (X is adapted according to context) for function 
>> scoped errors, and err for block scoped errors
>>
>> func MyFunc() error {
>>>   v, errDS := doSomething()
>>>   ...
>>>   errDA := doAnotherthing()
>>> }
>>>
>>
>> if err := doAnotherthing(); err != nil {
>>> return err
>>> }
>>>
>>
>> That way you don't shadow errors.
>>
>
>
> I can't +1 this enough.
>
> I've caught *so* many bugs from shadowed errors (and re-used error 
> variables). I consider it a rather bad anti-pattern to have a single err 
> variable 
> that's reused throughout a scope.
> If you have unique error variable names and you forget to do something 
> with an error that you've assigned a name you automatically get unused 
> variable compile-errors. (just this is enough to be worthwhile)
>
>
> With that said, constraining the scope using the initializer statement on 
> an if (or switch) statement suffices when you don't need any other return 
> values, at which point I may use the err variable-name (although I often 
> make those unique for clarity anyway).
>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>>
> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAF9DLCmR4ZdnVs4A28BSrPcbiHsQ_ufub5cSPjCt2SDy2dA1xA%40mail.gmail.com
>>  
>> 
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/6b493efc-79ad-43f7-8730-91abd9b6c9cfn%40googlegroups.com.


Re: [go-nuts] initialization loop ?

2021-10-23 Thread Michael Ellis
> The rules for when an initialization loop occurs are part of the language 
spec: https://golang.org/ref/spec#Package_initialization.

Thanks for the link.  It helps with questions I've had recently about 
package initialization.  Can you confirm that the statement

"If a package has imports, the imported packages are initialized before 
initializing the package itself. If multiple packages import a package, the 
imported package will be initialized only once"

means that if 
 - package x imports y and z (in that order), and
 - package y imports a
 - package a imports b
 - package z imports b

then b will be initialized during the initialization of y ( and not 
initialized again during the import of z)?

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/59051b16-7717-4035-9a9e-765dc894cda9n%40googlegroups.com.


Re: [go-nuts] Re: Questions about documentation of Go standard library

2021-10-07 Thread Michael Ellis
Kamil,
Have you read https://go.dev/blog/errors-are-values by Rob Pike?  Wrapping 
my head around the concept that an error is simply a value returned from a 
function was tremendously helpful when I had questions along the same lines 
as yours.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/724b763c-cd5d-4c9c-83f2-8c08cb739887n%40googlegroups.com.


[go-nuts] Re: Printing a slice of structs recursively

2021-09-02 Thread Michael Ellis
Here's one way. https://goplay.space/#5KzrUc0171N

On Thursday, September 2, 2021 at 1:03:48 AM UTC-4 seank...@gmail.com wrote:

> Try doing it recursively, passing in both the current parent id and 
> indentation level
>
> On Thursday, September 2, 2021 at 3:55:01 AM UTC+2 n.erde...@gmail.com 
> wrote:
>
>> i need some help with printing a slice of structs which there is a child 
>> - parent relation in the struct.
>> *type* Emp *struct* {
>> id   int
>> name string
>> parentID int
>> }
>> probably the best way to do it recursively but i couldnt manage to do
>> https://play.golang.org/p/jHcbu3uBgOD
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ae9b334a-67ab-4e5a-a1a6-a4e2a996a3ebn%40googlegroups.com.


Re: [go-nuts] Makefiles for Go Programs

2021-08-23 Thread Michael Ellis
Three cheers for mage .  It's more verbose than make 
but it's pure Go. I use it to build and test projects that include 
generated html/css/js supported by a Web Assembly clients communicating 
with a server.

On Monday, August 23, 2021 at 7:33:10 PM UTC-4 Connor Kuehl wrote:

>
>
> > On Aug 22, 2021, at 10:11 PM, jlfo...@berkeley.edu  
> wrote:
> > 
> > 
> > I've noticed that few, if any, Go programs use Makefiles. Is that 
> because the overhead of using make is greater than the overhead of just 
> always compiling and linking everything?
> > One piece of evidence for this is that the Go compiler leaves no 
> artifacts, like object files, so as is make wouldn't fit into the current 
> build method.
> > 
>
> I started using a Makefile for my Go project so that I could inject a 
> version string at build time without having to remember what to pass to go 
> binaries.
>
> I made a Discord bot to use in a server with my friends, and since I have 
> some automation in place to automatically deploy the tip of my main branch, 
> I thought it’d be convenient to be able to ask the bot what build it’s 
> running so we can see which commits are “live."
>
> So while it’s not a “traditional” use of make, it certainly is convenient.
>
> Connor
>
> P.S., here’s the Makefile. The important bits are the lines that mention 
> “LD_FLAGS"
>
> VERSION := v2.2.0+dev
> BUILD := $(shell git describe --tags 2>/dev/null || echo "$(VERSION)")
>
> LD_FLAGS := "-X 'main.Version=$(BUILD)'"
>
> SOURCES := $(shell find . -type f -name '*.go')
> SOURCES += go.mod go.sum
>
> .PHONY: build clean test
>
> all: popple
>
> popple: build
>
> build: $(SOURCES)
> @go build -v -ldflags=$(LD_FLAGS) ./...
>
> test: popple
> @go test -v -ldflags=$(LD_FLAGS) ./...
>
> clean:
> @rm -rf popple

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/6b2116b0-b6e1-4d60-bd88-ee71f011035en%40googlegroups.com.


Re: [go-nuts] Modules... why it has to be so painfull?

2021-04-09 Thread Michael Ellis
FWIW, I completely agree with the sentiment that confusing documentation 
has created pain and unnecessary difficulty for solo developers.  I try to 
keep in mind that Go was developed for use by large teams working on 
million line programs and that I'm lucky to be able to piggyback on the 
efforts of top-notch talent. 

That being said, here is a recipe that seems to work -- for my purposes at 
least.  It's really just a restatement of what others have said in this and 
related threads:

1. Create a directory that will hold your local projects.  I think it best 
not to use ~/go/src.  My directory is ~/localgo,  I'll use that name in in 
what follows, though there's nothing special about it.
2. Undefine GOPATH, e.g. unset GOPATH
3.  Initialize a module named for the directory, i.e. cd ~/localgo; go mod 
init localgo
4. Move your package and cmd project underneath ~/localgo. 
5. When importing local package named "somepkg" use import localgo/somepkg
6. If a package in your local directory is something you've published, you 
have three choices when importing it:

   - Import it from your published repository,
   - Import from your published repository and use "replace" to force the 
   import to use the localgo copy,
   - Import directly from localgo (as in item 5).

To make this a little more concrete here's a portion of my localgo tree 
with two packages and two command projects.  Notice that mypkg and myprog 
do not have go.mod files yet myprog is able to import mypkg and build 
without error.  Package tbchrom, on the other hand, is already (privately) 
published and versioned on GitHub.  It's still under development. Having it 
cloned under localgo allows me to reference it from command tbflash which 
is not yet published.  I'm using the replace statement in tbflash's go.mod 
file, i.e.,  replace github.com/Michael-F-Ellis/tbchrom v1.0.0 => 
/Users/mellis/localgo/tbchrom

localgo
├── go.mod
├── mypkg
│   └── pkg.go
├── myprog
│   └── main.go
├── tbchrom
│   ├── .git
│   ├── .gitignore
│   ├── .vscode
│   ├── go.mod
│   ├── go.sum
│   ├── parser.go
│   ├── parser_test.go
│   ├── rhythm.go
│   ├── rhythm_test.go
│   ├── smf.go
│   └── smf_test.go
└── tbflash
├── go.mod
├── go.sum
├── main.go
├── main_test.go
└── tbflash.json

I like this solution because it's consistent and flexible. It's consistent 
in that all the go toolchain commands,  vet, build, ... etc., work the same 
regardless of whether a package or command if version controlled or has a 
go.mod file.  It's flexible, in large part, because it's consistent. I can 
start a project with bare Go code and add module support and version 
control as needed.

Hope someone finds it useful.  If you know of any awful pitfalls, please 
let me know.

On Friday, April 9, 2021 at 5:34:37 PM UTC-4 ohir wrote:

> Dnia 2021-04-07, o godz. 14:31:07
> Slawomir Pryczek  napisał(a):
>
> > Anyone has an idea for a reasonable solution which will allow easy 
> > refactoring and code organization in packages, in this new model?
>
> Idea is here: https://github.com/golang/go/issues/44347
>
> Whether is it reasonable or not — objectively — I can not tell as I am an 
> author.
> Though I'd like to see other's opinion whether proposed solution would 
> work for them.
>
> TC.
>
> -- 
> Wojciech S. Czarnecki
> << ^oo^ >> OHIR-RIPE
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/34e47688-3644-4005-a226-262fc2c480bfn%40googlegroups.com.


[go-nuts] Re: encoding/html package to generate html markup programmatically

2021-03-15 Thread Michael Ellis
goht  might be what you're looking 
for.

On Sunday, March 14, 2021 at 7:36:52 PM UTC-4 atd...@gmail.com wrote:

> Hi,
>
> I am currently thinking about implementing SSR for a Go client-side 
> framework.
> Not only that but I would like to be able to create static html from the 
> same code I use to create dynamic  wasm-based webapps.
>
> I was trying to find a package that would enable me to generate an html 
> document but seems like none exists.
>
> Do you think it is possible to use encoding/xml to create an xhtml 
> document?
>
>
> That would allow me to create something like MarkupPy that would replace 
> js DOM created element by html element.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/33063788-a96e-40f3-820a-78a34b7725f1n%40googlegroups.com.


Re: [go-nuts] Modules and internal packages

2021-03-04 Thread Michael Ellis
Just to close the loop, I've got a solution that's working well enough for 
my personal use.  

It takes advantage of GitHub's Template repo feature and the gh CLI tool to 
simplify the process of creating a new repository with a clone of the 
skeleton and a local copy thereof.  Using Axel's suggestion (thx!), I added 
an Init section to the magefile to walk the project tree changing any 
import references to match the new repo before building the app for the 
first time.

Thanks again for the help and explanations.
On Thursday, March 4, 2021 at 11:46:49 AM UTC-5 Michael Ellis wrote:

> On Thursday, March 4, 2021 at 11:01:06 AM UTC-5 axel.wa...@googlemail.com 
> wrote:
>
>> On Thu, Mar 4, 2021 at 4:51 PM Michael Ellis  
>> wrote:
>>
>>> My bad. I should have tested before writing that.  Thanks for checking.  
>>> Good to know the tools are enforcing the distinction.  Still, the import 
>>> path requirement does get in the way of being able to create a new 
>>> application by cloning and revising an existing one without doing a 
>>> recursive sed (or equivalent thereof).
>>>
>>
>> I agree :) And as I said, we could probably make relative imports work. 
>> But currently, the mapping from import paths to packages in a single go 
>> binary is 1-1. If we would allow you to use relative imports *as well,* 
>> that would be lost. Or we would have to force you to do one *or* the 
>> other per module. Either way, it seems like a non-trivial and potentially 
>> confusing transition. At which point we get back to "your usecase seems 
>> fairly special". Not "using internal packages", but the entire "cloning an 
>> existing project/skeleton and expect to have that just work as the 
>> jumping-off point for a new one". Note that *some* search/replace like 
>> stuff is still going to be needed anyway - at the very least, `go.mod` 
>> needs to contain a user-chosen module path.
>>
>> That's why I really don't think it's worth changing. Overall, your 
>> use-case seems much better addressed by writing a tool that generates your 
>> skeleton, replacing paths as needed, instead of expecting `git clone` to 
>> serve that purpose.
>>
>  
> Ok. Thanks for coherent explanation of why it may be hard to support 
> relative imports.  The skeleton code already has a fair amount of code 
> generation at build time, so it's not unreasonable to add an "Init" target 
> to the magefile that modifies go.mod.  I'll look into ways (build tags?) to 
> avoid using internal if possible.
>
> I disagree that cloning and modifying existing projects is special.  Good 
> lord! I (along with about a million other engineers) have been doing that 
> for decades:-) My clients really don't want and shouldn't have to pay me to 
> start from scratch every time.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f29b9eaa-a8cc-49aa-9291-db77e81c06b0n%40googlegroups.com.


Re: [go-nuts] Modules and internal packages

2021-03-04 Thread Michael Ellis


On Thursday, March 4, 2021 at 11:01:06 AM UTC-5 axel.wa...@googlemail.com 
wrote:

> On Thu, Mar 4, 2021 at 4:51 PM Michael Ellis  wrote:
>
>> My bad. I should have tested before writing that.  Thanks for checking.  
>> Good to know the tools are enforcing the distinction.  Still, the import 
>> path requirement does get in the way of being able to create a new 
>> application by cloning and revising an existing one without doing a 
>> recursive sed (or equivalent thereof).
>>
>
> I agree :) And as I said, we could probably make relative imports work. 
> But currently, the mapping from import paths to packages in a single go 
> binary is 1-1. If we would allow you to use relative imports *as well,* 
> that would be lost. Or we would have to force you to do one *or* the 
> other per module. Either way, it seems like a non-trivial and potentially 
> confusing transition. At which point we get back to "your usecase seems 
> fairly special". Not "using internal packages", but the entire "cloning an 
> existing project/skeleton and expect to have that just work as the 
> jumping-off point for a new one". Note that *some* search/replace like 
> stuff is still going to be needed anyway - at the very least, `go.mod` 
> needs to contain a user-chosen module path.
>
> That's why I really don't think it's worth changing. Overall, your 
> use-case seems much better addressed by writing a tool that generates your 
> skeleton, replacing paths as needed, instead of expecting `git clone` to 
> serve that purpose.
>
 
Ok. Thanks for coherent explanation of why it may be hard to support 
relative imports.  The skeleton code already has a fair amount of code 
generation at build time, so it's not unreasonable to add an "Init" target 
to the magefile that modifies go.mod.  I'll look into ways (build tags?) to 
avoid using internal if possible.

I disagree that cloning and modifying existing projects is special.  Good 
lord! I (along with about a million other engineers) have been doing that 
for decades:-) My clients really don't want and shouldn't have to pay me to 
start from scratch every time.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/8f73006c-f3b2-42ee-a754-29d13bc5fa89n%40googlegroups.com.


Re: [go-nuts] Modules and internal packages

2021-03-04 Thread Michael Ellis


On Thursday, March 4, 2021 at 10:06:01 AM UTC-5 Bryan C. Mills wrote:

>
> I would argue that the “hack” in this case is the approach of defining the 
> API in terms of copying in an entire tree of packages, rather than having 
> users of the API make function calls into a specific set of (unmodified, 
> un-relocated) packages with stable import paths.
>
> If the API is defined in terms or reflection over a set of types, why 
> substitute a package rather than (say) having the caller pass in a set of 
> instances of `reflect.Type` or similar?
>

I'm not trying to create an API.  My initial goal is to provide a working 
skeleton app for my own use that incorporates:

   - a server,
   - a wasm client,
   - a web page that loads the client,
   - a common struct that represents information to be displayed in the 
   page, changed by controls therein, and propagated back to the server 
   through the wasm client.
   - magefiles and templates that generate code in the server, client and 
   web page such that changes in the common struct are updated in all of the 
   above at build time.

The above functionality is working pretty well. I can modify, add or 
subtract members in the common struct, rebuild and run it with no other 
manual changes.  I posted here because of the problems I've encountered 
with Go modules when trying to create new app from a clone of the skeleton.

If I can make the skeleton broadly useful and make it play nice with Go 
modules,  I'll happily share it.  

 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/d83c42f9-0892-49f4-b41c-fdd05e216eb1n%40googlegroups.com.


Re: [go-nuts] Modules and internal packages

2021-03-04 Thread Michael Ellis


On Thursday, March 4, 2021 at 10:14:03 AM UTC-5 axel.wa...@googlemail.com 
wrote:

> On Thu, Mar 4, 2021 at 3:54 PM Michael Ellis  wrote:
>
>> Not sure if my case is all that special.  Seems like the requirement for 
>> a full path to an internal package breaks the concept of "internal" because 
>> it gives everyone import access to whatever the internal package exports.
>>
>
> Really? I can't reproduce that. If I create a minimal module importing "
> github.com/Merovius/srvfb/internal/fb" and try to build that, I get an 
> error message:
>
>  foo.go:3:8: use of internal package github.com/Merovius/srvfb/internal/fb 
> not allowed
>
> So, the internal mechanism seems to work just fine, to me? Note that 
> "every importer needs to mention the full path" is not the same as 
> "everyone mentioning the full path can import".
>

My bad. I should have tested before writing that.  Thanks for checking.  
Good to know the tools are enforcing the distinction.  Still, the import 
path requirement does get in the way of being able to create a new 
application by cloning and revising an existing one without doing a 
recursive sed (or equivalent thereof).

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/35e46b0e-a730-4b27-9ca0-313ddfccf855n%40googlegroups.com.


Re: [go-nuts] Modules and internal packages

2021-03-04 Thread Michael Ellis


On Thursday, March 4, 2021 at 2:24:11 AM UTC-5 axel.wa...@googlemail.com 
wrote:

> On Thu, Mar 4, 2021 at 12:55 AM Michael Ellis  
> wrote:
>
>> Thanks even though it's not the answer I was hoping for.  Seems to me 
>> that since the Go Authors have accorded special status to directories named 
>> "internal"  the module mechanism should recognize references to it and not 
>> require a globally unique path string.  
>>
>  

>  
>>
> Maybe. There seem to be few downsides. Then again, your case is also 
> fairly special.
>

Not sure if my case is all that special.  Seems like the requirement for a 
full path to an internal package breaks the concept of "internal" because 
it gives everyone import access to whatever the internal package exports.  
It would be good to have Russ and/or Ian weigh in on this.  My feeling at 
this point is that either "internal" should be deprecated or the module 
mechanism needs to honor it.
 

>
> On Thu, Mar 4, 2021 at 3:34 AM 'Bryan C. Mills' via golang-nuts <
> golan...@googlegroups.com> wrote:
>
>> You should be able to use a `replace` directive to replace the full path "
>> github.com/Michael-F-Ellis/skeleton/internal/common" or similar.
>
>
> Using replace would still mean that a module doesn't work, when used as a 
> library. Generally, I feel that `replace` is being used for more and more 
> things it wasn't designed for, leading to more and more friction and 
> problems. I don't think we should encourage more off-label uses. 
>

Agree. Replace in this instance feels like a hack. Don't get me wrong, I 
like the concept behind go.mod and think it's generally a strong and useful 
design. That being said, I also agree with the sentiment expressed in a 
couple of other recent thread that the present implementation imposes a 
burden on coders who want to quickly sketch and test ideas in a local 
directory.  It ought to be possible to progress at least a little way 
beyond Hello World before needing an external repo.


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c7f87f45-b944-4f00-a6a6-ad3a8d1c5d4bn%40googlegroups.com.


Re: [go-nuts] Modules and internal packages

2021-03-03 Thread Michael Ellis


On Wednesday, March 3, 2021 at 6:11:38 PM UTC-5 axel.wa...@googlemail.com 
wrote:

> On Thu, Mar 4, 2021 at 12:02 AM Michael Ellis  
> wrote:
>
>> What's the right way to handle this use case?
>>
>
> I think the right way to handle it is to modify the file. In the final 
> code, the import path should unambiguously point to where the code can be 
> found - regardless of whether it was using your skeleton to get started. 
> You might write a tool to do that modification automatically, if you want 
> to simplify things.
>

Thanks even though it's not the answer I was hoping for.  Seems to me that 
since the Go Authors have accorded special status to directories named 
"internal"  the module mechanism should recognize references to it and not 
require a globally unique path string.  

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/63067d97-1aa3-4efb-92af-7ea0f831a873n%40googlegroups.com.


[go-nuts] Modules and internal packages

2021-03-03 Thread Michael Ellis

I recently coded up a skeleton app to use as a starting point for projects 
that include a server component and a wasm (WebAssembly) client that does 
local work in a user's browser while communicating with the server.  

The skeleton is hosted  on Github (in a private repo until I think it's 
ready to publish).  

Today I decided to clone it and start an actual project.  I've run into a 
problem with internal package imports.  

Briefly,  the skeleton has multiple source files  that import from internal 
packages, e.g.

import  "github.com/Michael-F-Ellis/skeleton/internal/common"

The purpose of the internal/common package is to define structs that need 
to be known by both the server and the wasm component.  As such, the 
package will be different in each application built from the skeleton and, 
hence, the import statements all need to be modified to reference the new 
project's module name, e.g.,

import  "gitlab.com/SomeOneElse/someproject/internal/common"

Is there now no way to simply refer to "internal/common" in the import 
statement and have the toolchain treat it as a local import.  I've tried 
using the various argument to a replace directive in go.mod with no luck so 
far.

What's the right way to handle this use case?



-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/669b426e-5d0a-43a4-b086-e9e0c7213a9en%40googlegroups.com.


Re: [go-nuts] Error handling

2021-02-20 Thread Michael Ellis
FWIW,  I've put together a tiny package that, with some tradeoffs, seems 
useful for reducing boilerplate in the common case where a function simply 
wants to return an error to its caller.  

https://github.com/Michael-F-Ellis/ro

The code is almost trivial. It consists of two small functions, 
ro.RecoverOn( err *error) and ro.ReturnOn(err error), used as follows:

import "github.com/Michael-F-Ellis/ro" 

func myfunc() (err error) { 
defer ro.RecoverOn() 

err = SomeFunctionCall() 
ro.ReturnOn(err)

// Do more stuff 
// ... 
return 
}

ReturnOn panics if err is not nil.

RecoverOn recovers from the panic raised by ReturnOn and the function exits 
with whatever error value would have been returned normally. RecoverOn does 
not interfere with panics arising outside of ReturnOn.

Benefits and tradeoffs (coding discipline, debugging, performance) are 
discussed in the README.

Feedback welcomed either in this thread or in the repo issues.

On Saturday, February 20, 2021 at 3:31:22 PM UTC-5 matthew...@nytimes.com 
wrote:

> I'm referring to errors found in the function (i.e., by calling 
> other functions). It's the responsibility of the callers of a function to 
> handle the errors it returns, and not the function itself. How can one 
> function claim responsibility for the error handling strategy of all 
> programs using it?
>
> Yes, I suppose in some sense exceptions guarantee all errors are handled 
> somewhere. Unfortunately, what I've seen of exception handling over the 
> years is that it's often "log the stack trace and keep moving", which isn't 
> all that useful, and tends to cover up real bugs. A better approach would 
> be not to catch exceptions at all, and let them crash the program (which is 
> what Go's panic will do); this ensures the bugs are really handled by 
> removing them from the program.
>
> [And given this type of exception "handling" it's not much value to the 
> author of a single function to know that the errors will all be "handled" 
> somewhere.]
>
> Unfortunately, exception handling languages tend to put all types of 
> errors, normal and abnormal *, into the same basket. Which means you can't 
> do sensible error handling for, e.g., JSON that doesn't decode, while 
> allowing the program to crash when there's a logic bug. (For non-safety 
> critical software, a crash failure is typically the safest way to fail. 
> Safety-critical software, on the other hand, avoids exception handling like 
> the plague.)
>
> * A normal error is some behavior that can reasonably be expected, such as 
> "file not found" or "no route to host", etc. Abnormal errors are logic bugs 
> in the program.
>
> An aside:
>
> Assuming you had a cyclomatic complexity calculator that took exceptions 
> into consideration, such that exceptions passing through a function counted 
> as a branch, what kind of numbers would you get? Probably pretty awful, 
> given just about any line of code would be capable of throwing an 
> exception. But exceptions typically aren't counted, so that functions are 
> thought to be far less complex than they really are in the presence of 
> exceptions.
>
> Invisible (magic) return paths through a function go against the notion of 
> "the code does what it says on the page".
>
> On Sat, Feb 20, 2021 at 1:11 PM Robert Engels  
> wrote:
>
>> Can you clarify what you mean mean by “the code does exactly what it 
>> shows on the page”? How do you know by looking at the code, or even 
>> compiling the code, that all possible errors returned by a function are 
>> handled? That to me is biggest difficult in reading (or using) others Go 
>> code. Exceptions (well written) handle this by declaring all possible error 
>> (or categories) thrown by the method. 
>>
>> This seems a real problem with long term maintenance of Go code. 
>>
>> On Feb 20, 2021, at 1:39 PM, Matthew Holiday  
>> wrote:
>>
>> 
>> Roger beat me to it.
>>
>> But allow me to rephrase,
>>
>> "The users of Go for a long time have resisted any changes to its simple, 
>> clear method of error handling despite it being a major concern of folks 
>> who don't use Go much." *
>>
>> * I'm referring to the original survey, which was worded along the lines 
>> of "what keeps you from adopting Go?"
>> (implying that the responders are those who haven't adopted Go)
>>
>> Any type of error handling that creates invisible returns in a function 
>> is a bad idea IMNSHO (an opinion backed up by various researches into the 
>> complexity of exception handling). Speaking for myself, I'd like to retain 
>> that quality of Go whereby "the code does exactly what it says on the page."
>>
>>
>> On Sat, Feb 20, 2021 at 11:31 AM roger peppe  wrote:
>>
>>>
>>>
>>> On Sat, 20 Feb 2021, 16:31 L Godioleskky,  wrote:
>>>
 Rust lang, very early in its evolution, saw the need to create its 
 operator '?'  to more efficiently manage error handling. But the guardians 
 of Go lang have resisted any changes to its clumsy 

Re: [go-nuts] What compatibility of go/ast, go/types, go/packages packages is planned, if any, when transitioning toward go2 ?

2021-02-14 Thread Michael Ellis
On Wednesday, 27 January 2021 at 23:28:17 UTC+1 Ian Lance Taylor wrote:
To be clear, there is no Go 2, and there are no plans for Go 2.

Speaking as one who suffered through the ill-conceived and interminable 
Python3 transition, this is the best news I've heard since discovering and 
falling in love (well, it *is* Valentines Day) with Go a couple of years 
ago.  Thank you!

On Thursday, January 28, 2021 at 2:26:37 PM UTC-5 Ian Lance Taylor wrote:

> On Thu, Jan 28, 2021 at 3:43 AM 'Carla Pfaff' via golang-nuts
>  wrote:
> >
> > On Wednesday, 27 January 2021 at 23:28:17 UTC+1 Ian Lance Taylor wrote:
> >>
> >> To be clear, there is no Go 2, and there are no plans for Go 2.
> >
> >
> > For someone who follows the mailing lists and issue comments this has 
> been known for a while, but it's easy to see where the confusion comes 
> from, given these blog posts:
> >
> > https://blog.golang.org/toward-go2
> > https://blog.golang.org/go2-here-we-come
> > https://blog.golang.org/go2-next-steps
> >
> > They mention backward-compatibility, but only for the initial proposals 
> "to get the ball rolling". There hasn't been a blog post titled "There are 
> no plans for Go 2" or "Go 2 is not what you think it is" so far. The 
> current policy seems to be this document:
> >
> > "Proposal: Go 2 transition": 
> https://go.googlesource.com/proposal/+/refs/heads/master/design/28221-go2-transitions.md
> > "If the above process works as planned, then in an important sense there 
> never will be a Go 2."
> >
> > It is labeled "Proposal", but it doesn't seem to be a proposal in the 
> usual proposal process sense, and many may have missed it.
>
> You're right, I wrote that poorly. People use "Go 2" in various
> different ways. I should have said: there is no plan to ever break
> backward compatibility with earlier versions of Go.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/77ade682-6cb2-45ee-b7bd-7447d3b41a7dn%40googlegroups.com.


Re: [go-nuts] Re: How to get VSCode to use different Go env vars for different directories in the same repo?

2021-02-14 Thread Michael Ellis
I've opened https://github.com/golang/vscode-go/issues/1225.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK6kDbZXw1HRs5tqX50LFfv%3Dg_drosjMXbN13_ELD5pYCyt8bQ%40mail.gmail.com.


Re: [go-nuts] Re: How to get VSCode to use different Go env vars for different directories in the same repo?

2021-02-14 Thread Michael Ellis
>
> As vscode-go is now curated by the Go team [
> https://blog.golang.org/vscode-go]
> I think you should raise issue at https://github.com/golang/vscode-go.
> Your project layout (original one) seems good and straightforward, and the
> need
> for having per-folder environment settings or build-tags is real.
> It shouldn't be the IDE that dictates Go project structure, IMO.
>

I agree about wanting project structure independent of IDE.  I'm not so
sure if this is something vscode-go can reasonably be expected to solve,
though.

If I'm understanding correctly,  vscode-go would need to parse each file
for build-tags and pass that information to the go tool chain, presumably
as environment variables.

That sounds doable for standard tags that map to supported values for GOOS,
GOARCH, etc., but I wonder what problems would be caused by non-standard
tags, e.g. "+build mage" for magefiles.


Cheers,
Mike

*“I want you to act as if the house was on fire. Because it is.” — Greta
Thunberg*


On Sun, Feb 14, 2021 at 11:32 AM Wojciech S. Czarnecki 
wrote:

> Dnia 2021-02-14, o godz. 10:54:02
> Michael Ellis  napisał(a):
>
> > I wrote a detailed answer on StackOverflow
>
> Thank you.
>
> As vscode-go is now curated by the Go team [
> https://blog.golang.org/vscode-go]
> I think you should raise issue at https://github.com/golang/vscode-go.
> Your project layout (original one) seems good and straightforward, and the
> need
> for having per-folder environment settings or build-tags is real.
> It shouldn't be the IDE that dictates Go project structure, IMO.
>
> TC,
>
> --
> Wojciech S. Czarnecki
>  << ^oo^ >> OHIR-RIPE
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/2vI1CA76HPI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/20210214173156.1a9edbfa%40xmint
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK6kDbZ8E7py6hX_8Bp7Z-gixoZg6MNeJzZy00Vr0y4zoBhyow%40mail.gmail.com.


Re: [go-nuts] Re: How to get VSCode to use different Go env vars for different directories in the same repo?

2021-02-14 Thread Michael Ellis
Thanks, Space & Alex.  I already understood the need for the Go tool
environment vars, just didn't know how to apply them on a per-folder
basis.  Thanks for outlining how to use multiple instances of VSCode.  It
doesn't appeal to my workflow preferences, but then *à chacun son goût* as *nos
amis français* would put it.

I ended up learning how to use VSCode Multi-Root Workspaces to permit a
separate settings.json in wasm/ folder.  That seems to work fairly well.  I
wrote a detailed answer on StackOverflow

for
anyone who's interested.

Cheers,
Mike

*“I want you to act as if the house was on fire. Because it is.” — Greta
Thunberg*


On Sun, Feb 14, 2021 at 7:11 AM Space A.  wrote:

> Hi,
>
> the solution would be:
>
> 1. Protect WASM source files with build flags so that when you open a
> "backend" main sources, IDE won't complain about "syscall/js", like this:
> // +build js,wasm
> 2. Open `wasm` directory in second instance of VS Code for which you would
> set GOOS and GOARCH for a workspace. When editing settings in json, click
> on "workspace" tab and VS Code will create .vscode/settings.json in `wasm`
> directory. Put something like:
> {
> "go.toolsEnvVars": {
> "GOOS": "js",
> "GOARCH": "wasm",
> }
> }
> in there.
> 3. In future, work in two instances of VS Code, even though if logically
> it's a different parts of same project and could be under the same Go
> module. All IDE features will work fluently. I haven't seen any problems
> with this approach so far.
>
>
> суббота, 13 февраля 2021 г. в 23:42:06 UTC+3, michael...@gmail.com:
>
>> *(Sorry for posting what is mostly a VSCode question. I've asked it on
>> StackOverflow without getting any responses.  Am reposting here in the hope
>> that some has already run into this problem and figured out how to deal
>> with it.)*
>>
>> I have a Go project that builds a WebAssembly (WASM)  app and a backend
>> server for it. Both pieces build and run without errors. VSCode, however,
>> produces an annoying linter error in the WASM app.
>>
>> ```
>> could not import syscall/js (no required module provides package
>> "syscall/js")
>> ```
>>
>> The problem, as I currently understand it, is that VSCode doesn't infer
>> from the build tags that it should invoke `gopls` with `env GOOS=js
>> GOARCH=wasm` and that one solution is to set these tags as workspace Go
>> environment vars.
>>
>> The app design, however, relies on providing a common internal package to
>> both the wasm and the server code so that each side sees some struct
>> definitions that simplify the interface between them. To that end, the repo
>> is organized (simplified view) as follows:
>>
>> ```
>> cmd
>> ├── internal
>> │   └── common
>> │   ├── common.go
>> │   └── common_test.go
>> ├── server
>> │   └── main.go
>> └── wasm
>> └── main.go
>> ```
>>
>> How can I configure VSCode to use `env GOOS=js GOARCH=wasm` when linting
>> the wasm directory and not for other directories?
>>
>>
>>
>>
>>
>> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/2vI1CA76HPI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/ed6caf0c-64ec-454d-8926-dc9cbb98d8a5n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK6kDbabC5Wh9XoFBnFGzKZZ6Ect1--xPwkPpSXDEUboarm0QQ%40mail.gmail.com.


[go-nuts] How to get VSCode to use different Go env vars for different directories in the same repo?

2021-02-13 Thread Michael Ellis
*(Sorry for posting what is mostly a VSCode question. I've asked it on 
StackOverflow without getting any responses.  Am reposting here in the hope 
that some has already run into this problem and figured out how to deal 
with it.)*

I have a Go project that builds a WebAssembly (WASM)  app and a backend 
server for it. Both pieces build and run without errors. VSCode, however, 
produces an annoying linter error in the WASM app.

```
could not import syscall/js (no required module provides package 
"syscall/js")
```

The problem, as I currently understand it, is that VSCode doesn't infer 
from the build tags that it should invoke `gopls` with `env GOOS=js 
GOARCH=wasm` and that one solution is to set these tags as workspace Go 
environment vars.

The app design, however, relies on providing a common internal package to 
both the wasm and the server code so that each side sees some struct 
definitions that simplify the interface between them. To that end, the repo 
is organized (simplified view) as follows:

```
cmd
├── internal
│   └── common
│   ├── common.go
│   └── common_test.go
├── server
│   └── main.go
└── wasm
└── main.go
```

How can I configure VSCode to use `env GOOS=js GOARCH=wasm` when linting 
the wasm directory and not for other directories? 





-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c6f30190-8bdf-4a75-b787-7501c711785bn%40googlegroups.com.


Re: [go-nuts] Digest for golang-nuts@googlegroups.com - 25 updates in 4 topics

2020-06-15 Thread Michael Ellis
Ok, I just can't help chiming in here. Given that a couple of snippets save
the extra keystrokes and a smart folder saves the screen space, it's hard
to see why this issue gets so much discussion.
Cheers,
Mike

*“I want you to act as if the house was on fire. Because it is.” — Greta
Thunberg*


On Mon, Jun 15, 2020 at 10:06 AM  wrote:

> golang-nuts@googlegroups.com
> 
>  Google
> Groups
> 
> 
> Topic digest
> View all topics
> 
>
>- political fundraising on golang.org!
><#m_-1714232165778969862_group_thread_0> - 20 Updates
>- go scheduler tracing <#m_-1714232165778969862_group_thread_1> - 1
>Update
>- The next layer of abstraction for Go development?
><#m_-1714232165778969862_group_thread_2> - 3 Updates
>- x, err = some_func(); if err != nil { } seems awkward
><#m_-1714232165778969862_group_thread_3> - 1 Update
>
> political fundraising on golang.org!
> 
> Ian Lance Taylor : Jun 14 04:30PM -0700
>
> Let's please all remember to be respectful and charitable in this
> discussion, per the gopher values in the code of conduct. Let's not let
> this go off the rails. Thanks.
>
> Ian
> Axel Wagner : Jun 15 02:14AM +0200
>
>
> > All I pointed out was that someone objecting to this may not be doing
> > based on political party affiliations.
>
> No, what you said is, that objecting to the banner may not be *political*.
> You didn't mention parties and neither did I. And I stand by my statement,
> that objecting to the banner *is* inherently a political act. And that
> claiming to object on the grounds that you don't want politics in the Go
> project is thus paradoxical.
>
> Do you think all Democrats think alike on all issues? This is the problem
> Jesse McNelis : Jun 15 11:51AM +1000
>
> On Mon, Jun 15, 2020 at 8:12 AM andrey mirtchovski 
> wrote:
>
>
> > I have a non-profit I'd like to support. Who do I ask to put a banner
> > on golang.org for me?
>
> > (reductio ad absurdum)
>
> This sounds like a great idea to me. It would probably need to be a
> non-profit that furthers the Go language by expanding the reach and appeal
> of the community to underrepresented groups.
> Perhaps someone could put together a policy on what kind of non-profits
> that would involve and this could be an ongoing thing.
> Jon Reiter : Jun 15 12:11PM +0800
>
> Except now sharing links to golang.org, or showing those web pages at
> events, could be argued as advocating for a foreign political cause. And
> that's illegal in much of the world. Per google, google operates in 219
> countries. This could force community members to argue in any of at least
> 219 legal systems this is apolitical under local law. Not the golang code
> of conduct, local law. That is a decision that impacts the entire
> community.
>
> On Mon, Jun 15, 2020 at 6:23 AM 'Dan Kortschak' via golang-nuts <
> Axel Wagner : Jun 15 08:48AM +0200
>
> I share link to golang.org all the time and I'd be willing to serve as a
> testcase for this. Feel free to report my alleged crimes to the police.
> Claiming that simply sharing a link to the Go page is "advocating for a
> foreign political cause" is clearly a bad-faith argument, so if you live in
> the kind of legal system where you aren't laughed out of the room by any
> judge you try to make it to, I feel that the content of the Go project page
> is the least of your worries.
>
> Also telling that you seem to explicitly call out the Go code of conduct as
> not "impacting the entire community"? Surely I misunderstood that. Just
> pointing that out to make clear that "it impacts the entire community" is
> pretty much par for the course for things the Go team does.
>
> Marian Kopriva : Jun 14 11:52PM -0700
>
> I agree with Peter's sentiment here.
>
> On Sunday, June 14, 2020 at 3:36:38 PM UTC+2, peterGo wrote:
> Rusco : Jun 15 02:16AM -0700
>
> This is political hijacking of the Golang project, I am disgusted !
>
>
>
>
>
>
>
> On Sunday, 14 June 2020 14:36:38 UTC+1, peterGo wrote:
> Axel Wagner : Jun 15 11:23AM +0200
>
> Can you be more specific about how this is a real issue? Like, do you have
> precedent, where a banner-ad was the reason someone who linked to a page
> for unrelated reasons was prosecuted? Would be interesting to have some
> real cases so we get a clear picture of the threat here.
>
> Because to be clear, the reason I am trivializing this, is because I
> believe it to be trivial. I can make up all kinds of laws and speculate
> around how what you may say is violating them. But just because it's laws I
> make wild claims about doesn't actually make the 

[go-nuts] Re: Go 1.14 Release Candidate 1 is released

2020-02-05 Thread Michael Ellis


On Wednesday, February 5, 2020 at 6:12:21 PM UTC-5, Andrey Tcherepanov 
wrote:
>
> Sorry to mention, but for me https://tip.golang.org/doc/go1.14 returns 
> "template: 
> main:846: unexpected EOF"
>
> Not sure if this is because it is work in progress, or too many people 
> trying to hit this site after announcement.
>

I'm seeing the same problem. 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b534f383-9421-4504-8816-df496a2ecdc7%40googlegroups.com.


[go-nuts] Re: A question !

2020-01-04 Thread Michael Ellis
I came to Go from 10+ years of Python (and 20 years of C before that).  Go 
By Example  was the online resource I found most 
useful in first few weeks of learning the language.  I also highly 
recommend getting a copy of The Go Programming Language 
and working your way through the chapters.  

For specific questions, this forum and Stack Overflow are both excellent.

Finally, it's been my experience that actually getting things done in any 
language comes down to mastery of its standard library. Plan to spend a lot 
of time in https://golang.org/pkg/.

Good luck in your journey!

On Saturday, January 4, 2020 at 1:28:24 PM UTC-5, Motaz Hejaze wrote:
>
> 2 - What is the fastest resource to learn Golang ( efficiently ) ?
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/e8d44ee2-4fa5-4078-85b8-48eb84354ca3%40googlegroups.com.


[go-nuts] Re: ANN: srctrace a tool to capture source code repository details

2019-11-17 Thread Michael Ellis
Nice. Thanks for sharing.

On Saturday, November 16, 2019 at 10:25:42 AM UTC-5, R Srinivasan wrote:
>
> friends
>
> The following is the first (of hopefully a few more to come) tools that I 
> built for DevOps. Hoping it will be of use to the community.
>
> https://github.com/RajaSrinivasan/srctrace.git
>
> best, srini
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/8e075920-2130-43f9-9a22-e30732f014da%40googlegroups.com.


[go-nuts] ANN: goht v1.0, a minimalist package for creating web content in Go

2019-11-14 Thread Michael Ellis

https://github.com/Michael-F-Ellis/goht

Easy to learn and practical for simple web development. I developed it for 
use in my own work and it seems worth sharing.

Cheers,
Mike

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/769e2aa9-ee80-4d1d-b540-bae2b20da7ae%40googlegroups.com.


[go-nuts] WasmFiddle for Go?

2019-11-12 Thread Michael Ellis
I came across WasmFiddle  a couple of 
days ago which lets you interactively code WebAssembly apps in C++.  Is 
anyone planning a similar capability for Go?

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/eabec914-7ee0-4c3a-ae5a-2cc1ceec88d4%40googlegroups.com.


Re: [go-nuts] Re: Auto-renew letsencrypt cert with standard library code

2019-11-06 Thread Michael Ellis



> Given how complex your file is, let me suggest you a simpler alternative: 
> use either caddy or revproxyry as a reverse proxy. You start two processes, 
> the reverse proxy and your service, and just point the reverse proxy to 
> your service. 
>
> Since reverse proxy is just a binary executable, the deployment is just 
> scp + ~5-10 lines config file + a super simple systemd config file.
>
>
Thanks, Marko, but I'm not sure that's simpler.  My unit file has exactly 
one line devoted to cert renewal.

ExecStartPre=+/usr/bin/certbot renew

All the rest is what's needed to run and  restart infinite-etudes under 
systemd.

Cheers,
Mike



 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2f901fed-f521-4bfd-84a6-933a52861f47%40googlegroups.com.


[go-nuts] Re: Auto-renew letsencrypt cert with standard library code

2019-11-06 Thread Michael Ellis
Thanks Sean Liao, Kurtis Rader, Marko Ristin-Kaufman, and cg-guy.  
Apologies for not responding sooner.

I looked at the code for Caddy and revproxyry.  Neat stuff for sure and I'd 
seriously consider them for a more elaborate project.

Thinking through my needs I concluded that it's probably better not to 
embed the process of obtaining and renewing certificates in the 
infinite-etudes code.  That way if someone chooses to run their own 
instance, they can do whatever makes the most sense within on their choice 
of host platform.

So I ended up biting the bullet and learning how to use systemd.  The unit 
file I ended up with is below. It sets Restart=always to ensure that the 
program reloads no matter what and uses ExecStartPre to attempt to renew 
the certificate before starting the server.  Seems reliable across reboots 
and killing the infinite-etudes process.  I won't know for sure until the 
cert actually expires in month or so but the logs show that certbot is 
being invoked whenever the service reloads.  It detects that the certs are 
unexpired and returns success on exit.

[Unit]
Description=Infinite Etudes server
After=network.target

[Service]
Type=simple
User=mellis
WorkingDirectory=/home/mellis/ietudes
# Always attempt to renew the certificate before (re)starting 
infinite-etudes
ExecStartPre=+/usr/bin/certbot renew
# infinite-etudes needs two environment variables that give full paths to 
the certificate
# fullchain and key files.
Environment="IETUDE_CERT_PATH=/etc/letsencrypt/live/etudes.ellisandgrant.com/fullchain.pem"
Environment="IETUDE_CERTKEY_PATH=/etc/letsencrypt/live/etudes.ellisandgrant.com/privkey.pem"
# run infinite-etudes as an https server
ExecStart=/home/mellis/go/bin/infinite-etudes -s -p :443
# Ensure that the process is always restarted on failure or if terminated 
by a signal
# A 5 second restart delay is used to reduce the possibility of thrashing if
# something is badly wrong.
Restart=always
RestartSec=5

[Install]

WantedBy=multi-user.target

Thanks, again, for the help.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/bca87840-abed-4af2-84d6-8169078f6ae0%40googlegroups.com.


[go-nuts] Auto-renew letsencrypt cert with standard library code

2019-11-05 Thread Michael Ellis

I have the code at the bottom of this message in a web server I'm 
running in a Digital Ocean Droplet.  The app is a simple ear training 
program for instrumentalists.  The URL is https://etudes.ellisandgrant.com.

It works with no problems until the letsencrypt certificate expires 
every 90 days.  ListenAndServeTLS() returns an error, the program exits and 
restarts (because I'm running under `entr - r`) and then falls into the 
default case which is plain http service.  I'd like to prevent that since 
modern browsers (for very good reasons) show scary warnings about plain 
http sites.  

I don't need absolute 100% uptime for the program.  A few minutes 
unavailability while the cert is renewed would be perfectly acceptable.  I 
just want to add a check at the restart to detect that the cert is expired 
and renew it automatically.  How can I do that with packages from the Go 
standard library?  ( I know Caddy is available but I'd prefer not to add a 
third-party dependency for what seems like a relatively simple task.)


var serveSecure bool
var certpath, certkeypath string
if hostport == ":443" {
certpath, certkeypath, err = getCertPaths()
if err != nil {
log.Printf("Can't find SSL certificates: %v", err)
hostport = ":80"
}
serveSecure = true
}
log.Printf("serving on %s\n", hostport)
switch serveSecure {
case true:
if err := http.ListenAndServeTLS(hostport, certpath, certkeypath, nil); err 
!= nil {
log.Fatalf("Could not listen on port %s : %v", hostport, err)
}
default:
if err := http.ListenAndServe(hostport, nil); err != nil {
log.Fatalf("Could not listen on port %s : %v", hostport, err)
}
}


/ getCertPaths attempts to retrieve a certficate and key for use with
// ListenAndServeTLS. It returns an error if either item cannot be found but
// does not otherwise attempt to validate them. That is left up to
// ListenAndServeTLS.
func getCertPaths() (certpath string, keypath string, err error) {
certpath = os.Getenv("IETUDE_CERT_PATH")
if certpath == "" {
err = fmt.Errorf("no environment variable IETUDE_CERT_PATH")
return
}
keypath = os.Getenv("IETUDE_CERTKEY_PATH")
if keypath == "" {
err = fmt.Errorf("no environment variable IETUDE_CERTKEY_PATH")
return
}
return
}

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/dc40264f-5314-496b-9069-81acbf94701a%40googlegroups.com.


Re: [go-nuts] go 1.13 won't compile

2019-09-30 Thread Michael Ellis
Robert,
It's probably worth a careful look at
https://github.com/golang/go/wiki/Modules#recent-changes and
https://golang.org/doc/go1.13#modules as well as Marcin's suggestion to run
go env. When I do the latter, I get

GO111MODULE=""
GOPRIVATE=""
(among many other variables but those are probably the important ones).
Those settings are working for me for projects that have modules and for
projects that don't.

One possibility is that some pieces of version 1.12 are still hanging
around.  As you  probably know the recommended approach to upgrading
requires removing the older version before installing the new.  See
https://golang.org/doc/install#uninstall

Cheers,
Mike

*“I want you to act as if the house was on fire. Because it is.” — Greta
Thunberg*


On Mon, Sep 30, 2019 at 12:21 PM Marcin Romaszewicz 
wrote:

> Could you post the output of "go env" run on linux mint? Maybe there's a
> clue in there.
>
>
> On Mon, Sep 30, 2019 at 9:14 AM Robert Solomon  wrote:
>
>> Then my question becomes, what's different about linuxmint 19.2 to
>> require me to set GO111MODULE=no
>>
>> On Mon, Sep 30, 2019, 11:06 AM Everton Marques 
>> wrote:
>>
>>> Your code from playground compiled fine for me on Debian Linux.
>>> Tested with Go 1.13 and 1.13.1.
>>>
>>> Just had to include the missing func:
>>>
>>> func GetUserGroupStr(f os.FileInfo) (string, string) {
>>> return "foo", "bar"
>>> }
>>>
>>>
>>>
>>> Em segunda-feira, 30 de setembro de 2019 11:34:52 UTC-3, Robert Solomon
>>> escreveu:
>>>>
>>>> Your experience matches mine when compiled on windows 10.
>>>>
>>>> But linuxmint experience is as I described.   Another responder asked
>>>> me if it works when I set GO111MODULE=no.
>>>>
>>>> It does work when I do that.   I find it interesting that the linux
>>>> behavior seems to be different
>>>>
>>>> On Mon, Sep 30, 2019, 9:17 AM Michael Ellis 
>>>> wrote:
>>>>
>>>>> FWIW, I copied your code from Go Playground into ~/go/src/dsrt/dsrt.go
>>>>> on my OS X machine.  I replaced an undefined function at line 375 (see
>>>>> below) with direct assignments for usernameStr and groupNameStr. It
>>>>> compiled (with go build) and ran without reporting an error under go 1.13.
>>>>>
>>>>> // usernameStr, groupnameStr := GetUserGroupStr(f) // util function in
>>>>> platform specific code, only for linux and windows.  Not needed anymore.
>>>>> Probably won't compile for foreign computer.
>>>>> // GetUserGroupStr() is undefined, so hardcode
>>>>> a couple of nonsense strings to test compilation.
>>>>> usernameStr := "foo"
>>>>> groupnameStr := "bar"
>>>>>
>>>>>
>>>>>
>>>>> On Saturday, September 28, 2019 at 2:55:51 PM UTC-4, rob wrote:
>>>>>>
>>>>>> I guess I was not clear enough.  My apologies.  dsrt is my own code.
>>>>>> I remember an earlier posting on this list recommended 'go install' 
>>>>>> instead
>>>>>> of 'go build'
>>>>>>
>>>>>> ~/go/src/dsrt/dsrt.go, util_linux.go, util_windows.go
>>>>>>
>>>>>> And I have written other small programs in go that I use for myself.
>>>>>> I put it in https://play.golang.org/p/U7FgzpqCh-B
>>>>>>
>>>>>> It compiles and runs fine on go 1.12.x under linux, and fine on go
>>>>>> 1.13 under windows 10.  I have not yet installed go1.13.1 on my windows 
>>>>>> 10
>>>>>> box.
>>>>>>
>>>>>> I remember a promise that anything that compiles under go 1.0.0 will
>>>>>> not be broken.  Not being able to compile using go 1.13 that works fine
>>>>>> using go 1.12.x, broke my code.
>>>>>>
>>>>>> I'm not a professional programmer.  I don't know what else to include
>>>>>> here to demonstrate my problem.
>>>>>>
>>>>>> Thanks for your response.
>>>>>>
>>>>>> --rob solomon
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 9/28/19 11:42 AM, Marcin Romaszewicz wrote:
>>>>>>
>>>>>> What was the last version of Go which wor

Re: [go-nuts] go 1.13 won't compile

2019-09-30 Thread Michael Ellis
FWIW, I copied your code from Go Playground into ~/go/src/dsrt/dsrt.go on 
my OS X machine.  I replaced an undefined function at line 375 (see below) 
with direct assignments for usernameStr and groupNameStr. It compiled (with 
go build) and ran without reporting an error under go 1.13.

// usernameStr, groupnameStr := GetUserGroupStr(f) // util function in 
platform specific code, only for linux and windows.  Not needed anymore.  
Probably won't compile for foreign computer.
// GetUserGroupStr() is undefined, so hardcode a 
couple of nonsense strings to test compilation.
usernameStr := "foo"
groupnameStr := "bar"



On Saturday, September 28, 2019 at 2:55:51 PM UTC-4, rob wrote:
>
> I guess I was not clear enough.  My apologies.  dsrt is my own code.  I 
> remember an earlier posting on this list recommended 'go install' instead 
> of 'go build'
>
> ~/go/src/dsrt/dsrt.go, util_linux.go, util_windows.go
>
> And I have written other small programs in go that I use for myself. I put 
> it in https://play.golang.org/p/U7FgzpqCh-B
>
> It compiles and runs fine on go 1.12.x under linux, and fine on go 1.13 
> under windows 10.  I have not yet installed go1.13.1 on my windows 10 box.
>
> I remember a promise that anything that compiles under go 1.0.0 will not 
> be broken.  Not being able to compile using go 1.13 that works fine using 
> go 1.12.x, broke my code.
>
> I'm not a professional programmer.  I don't know what else to include here 
> to demonstrate my problem.
>
> Thanks for your response.
>
> --rob solomon
>
>
>
> On 9/28/19 11:42 AM, Marcin Romaszewicz wrote:
>
> What was the last version of Go which worked for you? 
>
> "dsrt" isn't a valid module path in the new module resolution code. Does 
> it work if you disable modules - "GO111MODULE=off go install dsrt"?
>
>
>
> On Sun, Sep 22, 2019 at 9:56 AM rob > 
> wrote:
>
>> Hi.  I think I'm having an issue compiling my code w/ go 1.13.  I have 
>> not had any issues up until now.  I have my code in the default 
>> locations off of ~/go/src w/ a directory for each little bit of code I 
>> wrote.
>>
>> Running under linuxmint 19.2 amd64, I installed the go binary by first 
>> nuking /usr/local/go, and then
>>
>>  sudo tar -C /usr/local -xf go1.13.linux-amd64.tar.gz.
>>
>> When I run go version, I get go version go1.13 linux/amd64
>>
>> Now when I run
>>
>>  go install dsrt
>>
>> I'm getting an error message:
>>
>>  can't load package: package dsrt: mallformed module path "dsrt" : 
>> missing dot in first path element.
>>
>> I do not have, need or use a go.mod.  In fact, I don't really understand 
>> them.  And I don't yet understand what vendoring means.
>>
>> As an aside, I also compile on a win10 amd64 computer.  I installed 
>> windows binary in the usual way on that computer, compiled my code using 
>> go install, and I've not had any issues there.  I only have an issue 
>> here on linuxmint and go 1.13.
>>
>> What's up?
>>
>> --rob solomon
>>
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golan...@googlegroups.com .
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/3e9c5dad-2fda-9574-d8f9-8cedfb7986e5%40fastmail.com
>> .
>>
> -- 
> You received this message because you are subscribed to a topic in the 
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/golang-nuts/5hh--qle2KI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to 
> golan...@googlegroups.com .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29LtsWqufQHw%2BmJtAe60KnCHPag9SPVAtjkP2XzkkuHcwyg%40mail.gmail.com
>  
> 
> .
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/84d7a41b-5fff-428c-9e10-244ae2cc6a0b%40googlegroups.com.


Re: [go-nuts] Re: v1.13: Altered go.mod file in project after updating vim-go binaries

2019-09-05 Thread Michael Ellis
> current directory is. But if the current directory happens to be
> inside a module, the user inadvertently also performed (1).

Thanks, Mihai. That sounds like a consistent explanation.  I'm going to try
creating a new junk project to see if I can reproduce the problem.
Unfortunately, I'm going to be traveling for the next 2 days and won't have
time to try it until Sunday.  For the time being I've simply done a git
checkout to retrieve the prior go.mod and go.sum.




On Thu, Sep 5, 2019 at 3:53 PM Mihai Borobocea 
wrote:

> On Thu, Sep 5, 2019 at 10:18 PM Jan Mercl <0xj...@gmail.com> wrote:
> > `go get` should do just one thing and do it well. Automagically
> > adjusting `go.mod` if one is found in the current directory (or in any
> > of its parents) when outside $GOPATH is IMO neither of that. Or it
> > should be enabled by a flag, like -um (update go.mod) or this is maybe
> > a job for some `go mod foo` command, not `go get`.
>
> A-ha, I think I understand the problem: 'go get' can be used for two
> unrelated purposes:
> 1) to add/update dependencies in the current Go module
> 2) to install a program globally: 'go get golang.org/x/lint/golint'
> produces ~/go/bin/golint
>
> One normally wants to perform (2) from anywhere: like 'apt-get install
> ...' (or perhaps 'npm install -g ...'), it doesn't matter what the
> current directory is. But if the current directory happens to be
> inside a module, the user inadvertently also performed (1).
>
> If this is the case, it seems an issue worth addressing.
> However, I have only a basic understanding of go commands and modules.
> I might miss important details.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/-vUHGd5zlPI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAMXRBmi_Gpa9_DrmDXP8NKNP7YR2xi-ZSxuRGKcdqHbidZytcQ%40mail.gmail.com
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK6kDbYFGF4JVqJKZL1XzWw3MEzM7t5O_BLY2a6jStwJh%2BtZDQ%40mail.gmail.com.


Re: [go-nuts] Re: v1.13: Altered go.mod file in project after updating vim-go binaries

2019-09-05 Thread Michael Ellis
I second Jan's request for light-shedding.  It's one thing to add real 
indirect dependencies. I can sort of understand that.  Can't think of a 
sensible reason for adding dependencies that are unrelated to the code in 
the module. 

On Thursday, September 5, 2019 at 2:23:11 PM UTC-4, Jan Mercl wrote:
>
> On Thu, Sep 5, 2019 at 8:18 PM > wrote: 
>
> > Running 'go get ...' inside a module can add indirect dependencies to 
> go.mod. 
>
> I'm surprised. There's probably some rationale behind `go get` having 
> such side effects. Can anyone please shed some light on this? 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5de47c75-79ea-429c-866f-5091c5210426%40googlegroups.com.


[go-nuts] v1.13: Altered go.mod file in project after updating vim-go binaries

2019-09-05 Thread Michael Ellis
I've got an existing Go project that lives under GOPATH, i.e. 
~/go/src/github.com/...

I just updated to go 1.13 (from 1.12.1)  and rebuilt the project without 
changing any sources. The build succeeded and Go created a go.mod (and 
go.sum) file that containing my third party dependencies (there are only 
two of them).  Ok, that's nice, I thought. I added and committed go.mod and 
go.sum.

When I started editing sources (with NeoVim), I noticed that vim-go was no 
longer working, so I ran :GoUpdateBinaries.  It most succeeded with one 
complaint among the 2 dozen or so packages it updated.  It's still not 
working well in the editor, but that's not the point of this post.

I wrote some new code in one of my project files, running go vet from the 
command line several times until there were no errors.  When I looked at 
git status, I saw that the go.mod and go.sum files had changed.  My go.mod 
now contains lines for all vim-go dependencies!  WTF? None of those repos 
have anything to do with my project code.

Has anyone else encountered this? 

FWIW, here's what the require section now looks like.  The lines I've 
bolded are the prior content.

9fans.net/go v0.0.2 // indirect
github.com/alecthomas/gometalinter v3.0.0+incompatible // indirect
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 // indirect
github.com/cosiner/argv v0.0.1 // indirect
github.com/davidrjenni/reftools v0.0.0-20190827201643-0605d60846fb // 
indirect
github.com/fatih/gomodifytags v1.0.1 // indirect
github.com/fatih/motion v1.0.0 // indirect
github.com/go-delve/delve v1.3.1 // indirect
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf // indirect
github.com/josharian/impl v0.0.0-20190715203526-f0d59e96e372 // indirect
github.com/jstemmer/gotags v1.4.1 // indirect
github.com/keegancsmith/rpc v1.1.0 // indirect
github.com/kisielk/errcheck v1.2.0 // indirect
github.com/klauspost/asmfmt v1.2.0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/koron/iferr v0.0.0-20180615142939-bb332a3b1d91 // indirect
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-isatty v0.0.9 // indirect
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/mdempsky/gocode v0.0.0-20190203001940-7fb65232883f // indirect
github.com/peterh/liner v1.1.0 // indirect
* github.com/robfig/cron v1.2.0*
github.com/rogpeppe/godef v1.1.1 // indirect
github.com/sirupsen/logrus v1.4.2 // indirect
github.com/spf13/cobra v0.0.5 // indirect
github.com/stamblerre/gocode v0.0.0-20190327203809-810592086997 // indirect
github.com/zmb3/gogetdoc v0.0.0-20190228002656-b37376c5da6a // indirect
go.starlark.net v0.0.0-20190820173200-988906f77f65 // indirect
golang.org/x/arch v0.0.0-20190815191158-8a70ba74b3a1 // indirect
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 // indirect
* golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297*
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd // indirect
golang.org/x/tools v0.0.0-20190904211325-a4fdb3a8b281 // indirect
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c 
// indirect
honnef.co/go/tools v0.0.1-2019.2.3 // indirect


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7da3b1f0-a5c4-416e-a7c2-2d5ce2b6a8ce%40googlegroups.com.


Re: [go-nuts] The "leave "if err != nil" alone?" anti-proposal

2019-07-06 Thread Michael Ellis
> Exception handling when properly done is beautiful.
Yes and so are:

   - C++ templates
   - Python meta-classes
   - Scheme hygienic macros

but that doesn't mean Go would be improved by adding them.

On Friday, July 5, 2019 at 6:46:49 PM UTC-4, robert engels wrote:
>
> If you’ve suffered through bad code due to exceptions, you would just be 
> trading one ill for another. Exception handling when properly done is 
> beautiful. Yes, a lot of people get it wrong, but they would probably get a 
> lot of other things wrong as well. At least with exceptions, you have a 
> stack trace - usually - :) - to help you figure out what they did wrong. 
>
> > On Jul 5, 2019, at 5:29 PM, andrey mirtchovski  > wrote: 
> > 
> >> So I was quiet on the topic then - I am not now. 
> > 
> > i guess you missed the point where I advocated for a new survey, well 
> > advertised, where all the people who are fervent Go programmers but 
> > somehow neglected to fill out the Go surveys for three years running 
> > can cast their voice. "does go error handling need change: ◻️yes ◻️no 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> Groups "golang-nuts" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to golan...@googlegroups.com . 
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAK4xykXEtQZKeqyC8kLoHfokySD2xDzqY91hTz9_hMX%3DdkKtQg%40mail.gmail.com.
>  
>
> > For more options, visit https://groups.google.com/d/optout. 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c1c2b2db-b847-4cd9-80a6-317603d870d4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: General thoughts about new proposals

2019-07-04 Thread Michael Ellis
Well said, Slawomir. Your sentiments put me in mind of a favorite quote 
about writing prose.

*Vigorous writing is concise. A sentence should contain no unnecessary 
words, a paragraph no unnecessary sentences, for the same reason that a 
drawing should have no unnecessary lines and a machine no unnecessary 
parts. This requires not that the writer make all his sentences short, or 
that he avoid all detail and treat his subjects only in outline, but that 
every word tell.*
*-- Strunk & White, The Elements of Style*

I've treasured that advice since I first encountered it more than 3 decades 
ago.  I've become enamored of Go because it embodies the same commonsense 
spirit. Let's not screw that up.


On Thursday, July 4, 2019 at 6:02:45 AM UTC-4, Slawomir Pryczek wrote:
>
> Following this group for couple years and I think that from some time the 
> community is in some kind of crisis, because it seems that go1 is so good 
> that there's a lack of some feature which will distinct go1 from go2, so 
> everyone's trying to invent some code breaking change which will "distinct" 
> 1 from 2 just for the sake of breaking backward-compatibility. There are no 
> real issues with language design, so people seems to be "inventing" 
> problems ;)
>
> So we're having a flood of different specs, which are trying to "fix" 
> something that's not broken by adding needless complexity or adding a 
> "feature" from C or Java which is more complicated than the whole go1 when 
> we look at it for more than 2 minutes. And go1 is so good it seems so easy 
> to introduce couple of very bad ideas into the language because in the end 
> it'll still looks nice.
>
> Generics, operator overloading, memory ownership, try-catch, precalculated 
> functions, and the list could go on-and-on. There's C++, everyone's 
> favourite "missing feature" is already there ... probably that's why it's 
> such a delight to write anything in it with >1 person in team ;) And if you 
> "just" miss try/catch and generics it's called java. So much effor went 
> into making go simple to read and develop, and to remove all "dust" which 
> C++ gathered over the years, now I think so much thinking goes into 
> bringing it all back. I think when creating specs people are totally 
> missing the point... we thankfully don't have to deal with overloading or 3 
> different kind of for-loops so we can focus on algorithms because code is 
> easy to read. Since when replacing 3 different loop keywords for 3 
> different conditional keywords plus adding code fragmentation sounds like a 
> good idea? So when reading single line, we'll have to check specs and maybe 
> 4 other places in the file to be kind-of-sure what it does, like it happens 
> in C++, just to save a newline...
>
> It's really not about the specs, but the amount of support every change 
> usually gets, seems just for the sake of changing something. I'm afraid 
> some of these could be introduced, and the language will be going towards 
> becoming some kind of bad c++ clone. And we could end up with something 
> even as bad and unstable as node-js very quickly, because it seems that 
> currently google is the only force which keeps potential feature creep in 
> check. Really surprising how fast people forgot how horrible try/catch or 
> generics are. And (especially for generics and overloading) - how 
> unreadable and unmaintainable code using it really is. For sure there's 
> room for improvement by inventing some new ways of doing things... not 
> forcefully porting bad, decades old, error prone "ways of thinking" from 
> C'ish languages, so we can spare a newline here and there or avoid typing 3 
> chars...
>
> So just my 2c for keeping simplicity. And if go2 can compile go1 code 
> without changes, that's actually a feature not a "problem" and anyone can 
> create overly complicated system, so yes simplicity isn't a "problem" as 
> well ;)
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/cc274c1b-99e6-45b1-bd2c-2270ce30ca17%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: `on err` alternative to `try()` has traction...?

2019-07-04 Thread Michael Ellis
As noted by Aston, Jones, et al, the proposal is combining two ideas that 
are separable:


   1. Allowing one-liners. I like the idea of leaving that to gofmt. I'd be 
   ok with requiring braces and allowing gofmt to make the decision to format 
   in one line or three using some reasonable criterion.
   2. A test for not nil.  In my view, saving a few keystrokes is not the 
   reason to support such a test. I've already got an editor snippet that 
   generates a default "if err != nil ... " clause.  It just seems to me that 
   "on err { doSomething }" is worth allocating a keyword for the (admittedly 
   minor) gain in readability.  Note: The actual proposal is more general than 
   that. It defines 'on' as a test against the zero-value for the variable's 
   type. I'm not sure that's a good idea. Seems messy if it were allowed to 
   struct types.



On Thursday, July 4, 2019 at 4:55:50 AM UTC-4, Slawomir Pryczek wrote:
>
> On one side, it's 1000x better than the other error handling specs, at 
> least it isn't going to turn code into unreadable, fragmented mess. On the 
> other, Aston seems to have a point, it's just replacing one-liner... and 
> it's not that great at all because with "if" you know what it's doing 
> without reading the spec.
>
> My point is it doesn't fix anything, it doesn't provide any clear 
> benefit... it's an attempt to fix something which works great and is 
> clearly not broken. So why complicate the language with a new keyword which 
> has really no purpose. Maybe adding a warning about unhandled errors to VET 
> would be better idea (which would probably be complicated to do properly, 
> but at least it'll have some real, positive effect on code quality).
>
>
> W dniu wtorek, 2 lipca 2019 21:57:24 UTC+2 użytkownik Liam napisał:
>>
>> This proposal has attracted modest attention from the Go team...
>> https://github.com/golang/go/issues/32611
>>
>> It suggests:
>>
>> err := f()
>> on err, 
>>
>> on err, return err// any type can be tested for non-zero
>> on err, return fmt.Errorf(...)
>>
>> on err, fmt.Println(err)  // doesn't stop the function
>> on err, continue  // retry in a loop
>>
>> on err, goto label// labeled handler invocation
>> on err, hname // named handler invocation
>>
>>
>>
>> And offers these possible extensions:
>>
>> on err, os.IsNotExist(err):  
>> on err, err == io.EOF:   
>> on err, err.(*os.PathError): // doesn't panic if not a match
>>
>> on err, : 
>> on err:   // this pair provides if/else in 2 lines
>>
>> on err := f(),  // for assignment with single lvalue
>>
>>
>>
>> Other punctuation is possible, e.g. on (err) 
>>
>> Now if we could just convince the Go gods to prototype this along with 
>> try() in 1.14 :-)
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/adb9a65b-13a1-40e0-8b9b-b28fe80d07c8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: `on err` alternative to `try()` has traction...?

2019-07-03 Thread Michael Ellis
I like this. A lot.

It's clean and explicit.  The reader only needs to understand that 'on' is 
a test for a nil value (vs 'if' which tests for boolean true).



On Tuesday, July 2, 2019 at 3:57:24 PM UTC-4, Liam wrote:
>
> This proposal has attracted modest attention from the Go team...
> https://github.com/golang/go/issues/32611
>
> It suggests:
>
> err := f()
> on err, 
>
> on err, return err// any type can be tested for non-zero
> on err, return fmt.Errorf(...)
>
> on err, fmt.Println(err)  // doesn't stop the function
> on err, continue  // retry in a loop
>
> on err, goto label// labeled handler invocation
> on err, hname // named handler invocation
>
>
>
> And offers these possible extensions:
>
> on err, os.IsNotExist(err):  
> on err, err == io.EOF:   
> on err, err.(*os.PathError): // doesn't panic if not a match
>
> on err, : 
> on err:   // this pair provides if/else in 2 lines
>
> on err := f(),  // for assignment with single lvalue
>
>
>
> Other punctuation is possible, e.g. on (err) 
>
> Now if we could just convince the Go gods to prototype this along with 
> try() in 1.14 :-)
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/decc63a5-9e65-4e96-929f-76d44cf19e14%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Allow methods on primitives

2019-06-09 Thread Michael Ellis
*type Content = Content_ | string*

That's a nice notation (and semantic). It certainly makes sense for this
case.  Count me as a vote in favor.


*“I want you to act as if the house was on fire. Because it is.” — Greta
Thunberg*


On Sun, Jun 9, 2019 at 1:37 PM Bakul Shah  wrote:

> On Jun 9, 2019, at 7:42 AM, Michael Ellis 
> wrote:
> >
> > On Sunday, June 9, 2019 at 9:56:43 AM UTC-4, Bakul Shah wrote:
> >
> > You are almost always going to call a string's Render function
> > (as you defined it in your original post) from a parent HTMLTree
> > struct' Render(), almost never in isolation -- except perhaps some
> > tests. So one suggestion is to deal with string rendering issues
> > in the parent HTMLTree struct's Render(). Now you can still say
> >
> >   Div("", P("id=1", "When in the course of ..."))
> >
> >
> > Perhaps I'm misunderstanding, but I don't see how to make that work for
> tags that can take both text or other elements without resorting to making
> the content arguments of type interface{}. That's doable and the
> performance penalty is negligible but it discards the benefit of Go's
> compile time type checks.
> >
> > For reference, I've pasted together the guts of my html rendering code,
> defined a couple of tag functions and added a short main to illustrate what
> I'm doing at https://play.golang.org/p/_qZ7Oyv2Foa
> >
> > Any suggestions for cleanly allowing passing strings appreciated.
>
> Actually this is a good candidate for sum-types, something I have
> wanted in Go (and IMHO something that fits in well). So for example:
>
> type Tree struct {
> T, A string
> C []Content
> empty bool
> }
>
> type Content_ interface {
> Render(b *bytes.Buffer, nindent int) error
> }
>
> type Content = Content_ | string
> ...
> Div("", "Here's a link", A("href=someURL", "to some URL"), "and so
> on").Render(, 0)
>
> This gives you better compile time checking and the same
> convenience as using interface{}. Unfortunately
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK6kDbb742rksFkTJ7Y2aeG%2B4G0XT-qujhC8V_Y7c8qWjGcbew%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Allow methods on primitives

2019-06-09 Thread Michael Ellis


On Sunday, June 9, 2019 at 9:56:43 AM UTC-4, Bakul Shah wrote:
>
>
> You are almost always going to call a string's Render function 
> (as you defined it in your original post) from a parent HTMLTree 
> struct' Render(), almost never in isolation -- except perhaps some 
> tests. So one suggestion is to deal with string rendering issues 
> in the parent HTMLTree struct's Render(). Now you can still say 
>
>   Div("", P("id=1", "When in the course of ...")) 
>
>
Perhaps I'm misunderstanding, but I don't see how to make that work for 
tags that can take both text or other elements without resorting to making 
the content arguments of type interface{}. That's doable and the 
performance penalty is negligible but it discards the benefit of Go's 
compile time type checks.

For reference, I've pasted together the guts of my html rendering code, 
defined a couple of tag functions and added a short main to illustrate what 
I'm doing at https://play.golang.org/p/_qZ7Oyv2Foa

Any suggestions for cleanly allowing passing strings appreciated.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c2d5558c-c5ae-42f2-ba5f-f512f9f765bf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Allow methods on primitives

2019-06-09 Thread Michael Ellis
I'm not disputing the wisdom of Go's design. As I said at the top of the 
initial post, I like Go the way it is and see no need for a Go 2.  

I was trying to find a clean solution to a specific use case:  nestable 
functions that generate html.  Since new methods on primitives are not 
allowed (for good reason as I now understand) I wanted to at least inquire 
about the possibility of loosening the restrictions on a very specific 
case:  function args whose type is effectively a string (or other 
primitive).  I get the point the about types being not the same in terms of 
Go's internal bookkeeping. However, in this particular narrow case I don't 
see a hazard to maintainability because the rule forbidding new methods on 
primitives excludes any possibility of confusion within the body of the 
function.

To my mind, having to define a type equivalent to a primitive solely for 
the purpose of implementing an interface detracts from readability.  But 
given that there's good reason for the requirement I think being able to 
pass the equivalent primitive as a function argument of that type seems 
like a potentially safe way to make the code more readable.

Just my $0.02

On Sunday, June 9, 2019 at 1:49:36 AM UTC-4, Michael Jones wrote:
>
> To emphasize the wisdom:
>
> With an implicit conversion like you mentioned, the F(x) invocation at
> the bottom expects B.SomeFunc() will be called but in fact,
> A.SomeFunc() will be called. That's why this is an error. You can
> still do F(A(x)), which explicitly makes a copy of x as an A.
>
>
> This is not just a "Go style" issue, this is the result of distilling 
> lessons of millions of C++ developer's billions of hours of debugging and 
> large program / large team / long timeline development experience. Things 
> that are missing from Go, or restricted in Go, or even "adversarial" in Go 
> are there mostly because of hard-won experience. Many subtle design virtues 
> are what's missing as much as what's present.
>
> On Sat, Jun 8, 2019 at 8:53 PM Burak Serdar > 
> wrote:
>
>> On Sat, Jun 8, 2019 at 3:22 PM Michael Ellis > > wrote:
>> >
>> >
>> > On Friday, June 7, 2019 at 3:01:04 PM UTC-4, Burak Serdar wrote:
>> >>
>> >>
>> >> If one library defines string.Render() for html, and another defines
>> >> another string.Render() for, say, a graphics library, which Render
>> >> will be called when I call "str".Render()?
>> >>
>> > Thanks for the explanation. That makes sense.  Thinking it over, I'm 
>> wondering what would be required for the compiler to recognize synonyms of 
>> the form 'type Foo Bar' and allow passing a Foo for an argument of type 
>> Bar.  The compiler knows the expected type of each function argument so it 
>> seems as if checking to see if a passed argument is a simple synonym for 
>> the expected type and doing a coercion doesn't seem like a big task.  Note 
>> that this is different than asking for, say, numeric conversion from int to 
>> float64 because those types are not synonyms.  I actually like the fact 
>> that Go forces you to explicitly convert numeric types.
>>
>> If you have:
>>
>> type A int
>> type B A
>>
>> then A and B are not synonyms, they are different types. Because of
>> Go's  type system:
>>
>> func (a A) SomeFunc() {}
>> func (b B) SomeFunc() {}
>>
>>
>> func F(value A) {
>>   value.SomeFunc()
>> }
>>
>> x:=B{}
>> F(x)
>>
>> With an implicit conversion like you mentioned, the F(x) invocation at
>> the bottom expects B.SomeFunc() will be called but in fact,
>> A.SomeFunc() will be called. That's why this is an error. You can
>> still do F(A(x)), which explicitly makes a copy of x as an A.
>>
>> This is one of the reasons why it is so easy to read and write Go
>> code. Most of the time you can comprehend the code with only local
>> knowledge.
>>
>>
>> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google 
>> Groups "golang-nuts" group.
>> > To unsubscribe from this group and stop receiving emails from it, send 
>> an email to golan...@googlegroups.com .
>> > To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/aa26152a-fc5c-4048-9d30-446960df0ea9%40googlegroups.com
>> .
>> > For more options, visit https://groups.google.com/d/optout.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and

Re: [go-nuts] Allow methods on primitives

2019-06-08 Thread Michael Ellis
Oops, got that the wrong way round. Should read "allow passing a Bar for
argument of type Foo".
Cheers,
Mike

*“I want you to act as if the house was on fire. Because it is.” — Greta
Thunberg*


On Sat, Jun 8, 2019 at 5:22 PM Michael Ellis 
wrote:

>
> On Friday, June 7, 2019 at 3:01:04 PM UTC-4, Burak Serdar wrote:
>>
>>
>> If one library defines string.Render() for html, and another defines
>> another string.Render() for, say, a graphics library, which Render
>> will be called when I call "str".Render()?
>>
>> Thanks for the explanation. That makes sense.  Thinking it over, I'm
> wondering what would be required for the compiler to recognize synonyms of
> the form 'type Foo Bar' and allow passing a Foo for an argument of type
> Bar.  The compiler knows the expected type of each function argument so it
> seems as if checking to see if a passed argument is a simple synonym for
> the expected type and doing a coercion doesn't seem like a big task.  Note
> that this is different than asking for, say, numeric conversion from int to
> float64 because those types are not synonyms.  I actually like the fact
> that Go forces you to explicitly convert numeric types.
>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/L8XXHw9eiqM/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/aa26152a-fc5c-4048-9d30-446960df0ea9%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/aa26152a-fc5c-4048-9d30-446960df0ea9%40googlegroups.com?utm_medium=email_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAK6kDbZx%2BwNNm7A7bx7Fx%2BDWQqy7qcBbtZiXoZaFbEqeNaZR8g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Allow methods on primitives

2019-06-08 Thread Michael Ellis

On Friday, June 7, 2019 at 3:01:04 PM UTC-4, Burak Serdar wrote:
>
>
> If one library defines string.Render() for html, and another defines 
> another string.Render() for, say, a graphics library, which Render 
> will be called when I call "str".Render()? 
>
> Thanks for the explanation. That makes sense.  Thinking it over, I'm 
wondering what would be required for the compiler to recognize synonyms of 
the form 'type Foo Bar' and allow passing a Foo for an argument of type 
Bar.  The compiler knows the expected type of each function argument so it 
seems as if checking to see if a passed argument is a simple synonym for 
the expected type and doing a coercion doesn't seem like a big task.  Note 
that this is different than asking for, say, numeric conversion from int to 
float64 because those types are not synonyms.  I actually like the fact 
that Go forces you to explicitly convert numeric types.


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/aa26152a-fc5c-4048-9d30-446960df0ea9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Allow methods on primitives

2019-06-07 Thread Michael Ellis
Count me among those who love the language just the way it is and regard 
the prospect Go 2.0 with dread and loathing born of the Python 3 
experience.  

That being said, there's one itty-bitty change I'd like to advocate: *Allow 
methods on primitives*.

I think I understand why allowing new methods on external packages is a bad 
idea because it introduces a form of the fragile superclass problem.  But 
surely there's nothing fragile about strings, ints and floats.

Being unable to define a method on a string is *not* a showstopper since 
one can always do "type Foo string" or use type-assertions. It's just that 
it's inelegant in the case of a function that takes a recursive struct as 
an argument if the leaves of the tree are strings.  For example

type HTMLTree struct {
tag string
attributes string
content * Content // 
}

type Content interface {
   Render()
}

// NOT ALLOWED
func (s  string) Render() {
}

So I have to do something like

type SC string
func (s SC) Render() {
}

but that means instead of being able to write

Div("", P("id=1", "When in the course of ..."))

one must use the wrapper type on every content string.

Div("", P("id=1", SC("When in the course of ...")))

Not the end of the world, but uglier than it ought to be, IMO.

Is there a way to get around this or, failing that, an explanation of why 
methods on primitives are verboten?

Thanks!






-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/6daa53b9-c2e6-48e8-b022-c8339d3b8dbc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: A good indicator of code quality

2019-06-07 Thread Michael Ellis


On Friday, June 7, 2019 at 12:01:40 PM UTC-4, jake...@gmail.com wrote:
>
>
> I don't know the reasons why you want such metrics, but I would strongly 
> caution against equating any automated metric with "code quality". 
>

Amen. To my mind the most useful metric is what a mentor of mine dubbed 
"maximum locality". He explained it this way: Go into a programmers cubicle 
and look through the little stickies on the wall that represent fixes and 
features to be added.  The quality of the code is the extent to which all 
of them can be implemented by changing one place in one file.

I have no idea how you'd ever automate that, at least not prospectively.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/e27979d6-45a9-4896-a379-490415c9b99a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] lock for assigning to different elements of an array

2019-02-02 Thread Michael Ellis


On Saturday, February 2, 2019 at 3:36:17 PM UTC-5, Jake Montgomery wrote:
>
> Always a good read on why that is still a problem:
> Benign Data Races: What Could Possibly Go Wrong? 
> 
> It is not specific to go, but mostly applies to any language, and is stuff 
> all developers should know. 
>

Thanks, Jake. That's a good write-up. 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] lock for assigning to different elements of an array

2019-02-02 Thread Michael Ellis


On Friday, February 1, 2019 at 5:38:49 PM UTC-5, robert engels wrote:
>
> The pseudo code for the correct code would look like:
>

Robert, thanks very much for the clear explanation and correct example. I'd 
totally forgotten that Go is threaded underneath the hood and was thinking 
only in terms of latencies and pre-emptive scheduling.  I'm amazed that the 
code I've written since diving into Go (six months ago) works at all.  One 
of my control system apps has been running on multiple hosts 24/7 for 
several months with no crashes or problems that look like data races so I 
guess I've been lulled into a false complacency. But you can bet I'll be 
testing it with -race going forward!

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] lock for assigning to different elements of an array

2019-02-01 Thread Michael Ellis


On Friday, February 1, 2019 at 11:11:24 AM UTC-5, robert engels wrote:
>
>
> for {
>if A.a > 100 {
>   break
> }
>
>
> Go routine #2 may never see the value of A.a change and so never exit the 
> loop.
>

I'm confused. I can see how that would fail if the test were A.a == 100 
since Go routine #1 might increment past 100 before #2 ,  but as written it 
seems wrong only if the application logic depends on Go routine #2 exiting 
the loop as soon as A.a reaches 100 (as opposed to any time afterward.) 

What am I missing?


>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Maximizing source locality: [ANN] ftee

2019-01-30 Thread Michael Ellis
About 3 decades ago, one of my mentors offered the thought that a really 
practical metric for software maintainability is the percentage of fixes 
and enhancements that require editing only one region of one file. As he 
put it: "Visit your programmers' cubicles and find out how many files have 
to be changed for each of those little yellow stickies on the wall."  
Hopefully no one is still tracking issues with stickies on the wall these 
days, but you get the idea.

Lately I've been working solo on an control systems app (now partially 
ported to Go)  where each change seems to require hitting at least three 
files not counting adding unit tests.  I started wishing Go could support 
multiple package declarations within the same file so I could write things 
like:

package common
type someStruct struct {
}
package client
func someCommand(){
}
package server
func someCommandHandler() {
}
// etc

I realize that's unlikely to happen, so I did the next best thing and wrote 
a little file splitter. It's used like this:

// FTEE common.go
type someStruct struct {
}
// FTEE client.go
func someCommand(){
}
// FTEE server.go
func someCommandHandler() {
}
// etc

It also support multiple output targets like 'FTEE foo,bar baz.grp ...'

It seems to be working pretty well so I thought I'd share it.

https://github.com/Michael-F-Ellis/ftee



 




-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] gosnip: run small snippets of Go code from the command line

2018-11-27 Thread Michael Ellis
This is convenient and useful. Thanks!

On Tuesday, November 27, 2018 at 8:52:26 AM UTC-5, Ben Hoyt wrote:
>
> Good idea -- done! The goimports way is a bit more advanced and featureful 
> too.
>
> I love how all these little tools are basically just wrappers around a 
> library package which does all the work, so you can reuse them in your own 
> code.
>
> -Ben
>
> On Sun, Nov 25, 2018 at 8:53 AM Sameer Ajmani  > wrote:
>
>> Instead of writing your own logic to resolve missing imports, could you 
>> run the goimports tool? It will automatically select imports from the 
>> standard library and GOPATH.
>>
>> S
>>
>> On Sat, Nov 24, 2018 at 5:06 PM Ben Hoyt > 
>> wrote:
>>
>>> I just finished a little tool called "gosnip" that allows you to run 
>>> little snippets of Go code from the command line:
>>>
>>> https://github.com/benhoyt/gosnip
>>>
>>> To use it, just type something like:
>>>
>>> $ gosnip 'fmt.Println("Hello world")'
>>> Hello world
>>>
>>> gosnip automatically adds (standard library) imports, rolls into into a 
>>> complete program, and uses "go run" to run it.
>>>
>>> To quote the "Why?" section in the README: I made gosnip because when 
>>> coding in Go I often want to try little snippets of code to see what they 
>>> do, for example, "how does format string %6.3f work again?" I could use the 
>>> Go playground, but it's nice to be able to use a one-line command. Also, I 
>>> often develop while offline on my bus commute, so don't have access to the 
>>> online Go playground (yes, I know it's possible to run the Go playground 
>>> locally).
>>>
>>> It was very handy to have go/parser available in the standard library, 
>>> and even nicer that it automatically provides the list of unresolved names 
>>> -- which I use to know what to import.
>>>
>>> "go run" isn't particularly fast for this use case, as it spawns the go 
>>> compiler, linker, and then the program itself. Seems to take about 250ms on 
>>> my macOS machine (and it's probably slower on Windows, as os/exec is 
>>> somewhat slower on Windows).
>>>
>>> If anyone knows a better way to run Go source, let me know. As much as I 
>>> like writing interpreters, it'd be a big job to write a Go compiler just 
>>> for this. In the meantime, 250ms will have to do.
>>>
>>> Feedback welcome!
>>>
>>> -Ben
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to golang-nuts...@googlegroups.com .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: Announcing pytogo. a crude but surprisingly effective Python to Go translator

2018-10-03 Thread Michael Ellis
Thanks, Ingo! Finding the names of things in the stdlib is always half the 
battle in learning to do useful things in a new language. I'm surprised my 
Google searches didn't turn those up.  Anyway, ParseInt and FormatInt and 
kin are now my new best friends.

Prior to trying pytogo, my strategy was to rewrite a central piece of the 
app that talks to all the other processes and then port the Python 
processes one at a time as goroutines.  That's working very well so far.  
It's using less CPU and RAM and seems more stable.  As I replied to Eric, 
pytogo seems like it might speed up the process of porting other pieces of 
the app by providing a good first draft.  

On Wednesday, October 3, 2018 at 2:57:49 PM UTC-4, Ingo Oeser wrote:
>
> Hi Michael,
>
> while I understand that you are having fun with the pytogo translator, 
> please note that a base36 encoder is already part of the Go stdlib
>
> Namely https://golang.org/pkg/math/big/#Int.Text supports a base of 36 
> for big integers and https://golang.org/pkg/strconv/#FormatInt supports 
> base 36 as well.
>
> Maybe this helps reducing the python code you need to convert as well as 
> speed up the result by accident. 
>
> Have fun! 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: Rule-swarm attacks can outdo deep reasoning

2018-10-03 Thread Michael Ellis
Nice writeup. Thanks.  Based on today's xkcd , I 
think Randall Munroe must have read it, too ;-)

On Tuesday, October 2, 2018 at 9:21:08 AM UTC-4, Eric Raymond wrote:
>
> Is promised in the thread on pytogo, I have blogged on the general topic 
> of rule-swarm attacks in the domain of language transformation.
>
> http://esr.ibiblio.org/?p=8153
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: Announcing pytogo. a crude but surprisingly effective Python to Go translator

2018-10-01 Thread Michael Ellis
Thanks, Eric. v1.1 runs to completion on my utils.py test case.  I'm 
finding that a good work flow involves commenting out all the functions in 
the output and fixing them up one at a time.  Here's what pytogo did for me 
on my base36encode function and what I had to do manually:

*python:*
def base36encode(number):
"""
Encode an integer as Base 36.
>>> base36decode('1BIGNUMBER')
134038991273283
"""
if not isinstance(number, int):
raise TypeError('number must be an integer')
if number < 0:
raise ValueError('number must be positive')


alphabet = '0123456789abcdefghijklmnopqrstuvwxyz'


base36 = ''
while number:
number, i = divmod(number, 36)
base36 = alphabet[i] + base36


return base36.upper() or alphabet[0]


*pytogo:*
func base36encode(number) {
`
Encode an integer as Base 36.
>>> base36decode('1BIGNUMBER')
134038991273283
`
if !isinstance(number, int) {
raise TypeError("number must be an integer")
}
if number < 0 {
raise ValueError("number must be positive")


}
alphabet := "0123456789abcdefghijklmnopqrstuvwxyz"


base36 = ""
while number {
number, i = divmod(number, 36)
base36 = alphabet[i] + base36


}
return strings.ToUpper(base36) || alphabet[0]
}

*final go code:*
Getting it to compile and run required:

   1. Removing the isinstance test on number. It's not needed in Go.
   2. Deciding what to do about the number > 0 test. I made it return an 
   error.
   3. Choosing types for the arguments and returns.
   4. Declaring i outside the encoding loop.
   5. Testing number explicitly against 0.
   6. Converting alphabet[i] to string
   7. Discarding the final OR against alphabet[0]
   8. Writing a divmod function

I'm not sure which, if any, of the above are feasible to automate. Which is 
not to say that pytogo isn't useful.  It provides a good rough draft and 
that's quite a lot.  I'll certainly keep using it.

My only immediate suggestion would be to consider yanking function doc 
strings from the body and outputting them as comments above the func line.

// divmod returns quotient and remainder from numerator and denominator.
func divmod(num, denom int64) (q, r int64) {
   q, r = num/denom, num%denom
   return
}

// base36encode encodes an integer as Base 36.
func base36encode(number int64) (err error, base36 string) {
   if number < 0 {
   err = errors.New("number must be positive")
   }
   alphabet := "0123456789abcdefghijklmnopqrstuvwxyz"

   var i int64
   for number > 0 {
   number, i = divmod(number, 36)
   base36 = string(alphabet[i]) + base36
   }
   base36 = strings.ToUpper(base36)
   return
}




-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: Announcing pytogo. a crude but surprisingly effective Python to Go translator

2018-09-30 Thread Michael Ellis
Thanks for sharing this (and I'm honored to make your virtual acquaintance, 
Eric). 

 I'd love to make use of pytogo my own project. I've got a little over 20K 
lines that still need translation.

So I cloned it and gave it a quick try.  It seems to be choking on doc 
strings of the form.

"""
Some docstring text.
"""

All of my functions and modules have doc strings in that format. 

In case it's useful as a sample for your development, I've attached the 
file I tried to convert.  It's a short collection of miscellaneous utility 
functions that didn't quite fit elsewhere in the project. Here's what comes 
out when I try to convert it.

$ cat utils.py | ./pytogo
"""
`
func iterf(func, sentinel, *args, **kwargs) {
"""
}


If I chop out the doc strings from the top of the module and the first 
function, iterf, it makes it through the first function (which I realize is 
probably impossible to represent in Go) and then gives up at the 
triple-quotes in the next function,

$ cat utils.py | ./pytogo
func iterf(func, sentinel, *args, **kwargs) {
return iter(lambda  { func(*args, **kwargs), sentinel)
}


func base36encode(number) {
"""
}




On Sunday, September 30, 2018 at 6:48:14 AM UTC-4, Eric Raymond wrote:
>
> I have mentioned before on this list that I am engaged in source 
> translation of a largeish Python prgram - 14KLOC - to Go.  I found the 
> automated AST-based translation tools already available unsatisfactory; 
> they don't produce a quality of Go code I would consider maintainable.  So 
> I wrote my own using crude, old-school regexp-bashing.
>
> This turned out to be surprisingly effective.  The following is from the 
> manual page:
>
> * Opens Python block scopes with { and closes them with }.
>
> * Changes docstrings to comments.
>
> * Changes comments from #-led to //-led
>
> * Translates Python boolean constants True, False to Go true, false
>
> * Translates Python "in range" to Go ":= range",  You will need to fix
>   up the comma and range clauses by hand.
>
> * Maps Python single-quote literals to Go double-quote literals.
>
> * Translates Python logical connectives and or not to Go && || !.
>
> * Changes Python None to Go nil.
>
> * Changes "def " at the left margin to "func ".
>
> * Common cases of various Python string library methods - capitalize(), 
> count(), endswith(), find(), join(), lower(), lstrip(), rfind(), replace(), 
> rstrip(), split(), startswith(), split(), upper() - are translated to Go 
> string library calls.
>
> * Some common Python standard library calls, notably from os and 
> os.filepath, are translated into Go equivalents. The result is not  
> guaranteed to be perfectly correct; a Python call that throws a signal on 
> failure may map into a Go function with an error return. But it will always 
> be a step in the right direction, and the Go compiler will respond with 
> indicative error messages.
>
> * The append() method of Python is translated to a call to Go's append 
> intrinsic.
>
> * Python's "del foo[bar]" is translated to Go "delete(foo, bar)". Note 
> that this can false-match on a list del with a numeric key; this
>   will throw a compilation error in Go and you can hand-fix it.
>
> * Trailing line-continuation backslashes are removed.
>
> * Python r-prefix string literals become Go backtick literals
>
> * Python try/finally/catch become pseudo-statements with delimited block 
> scopes.  You will need to fix these up by hand.
>
> * Single-line % expressions with a string-literal left hand and either 
> tuple or single-variable right hands are translated into fmt.Sprintf 
> calls.  You will need to translate %-cookies by hand; %r -> %v or %q is the 
> usual trouble spot.
>
> * Changes multiline strings to backtick literals. You'll need to fix up 
> backslash escapes and %-cookies yourself.
>
> * Many, but not necessarily all, cases where Go ":=" assignment can 
> replace a plain "=" assignment in Python are translated.
>
> This doesn't do a complete job, of course.  But it takes a lot of the pain 
> out of hand-translation, and it does preserve comments and structure.  
> Probably the automated block scope closing is the biggest single win; 
> that's a tedious, fiddly job by hand and mistakes are all too easy.
>
> Future releases will translate a larger subset of Python standard library 
> calls.
>
> The repository is at https://gitlab.com/esr/pytogo and the project home 
> page at http://www.catb.org/esr/pytogo/
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
"""
Miscellaneous utility functions.
"""
def iterf(func, sentinel, *args, **kwargs):
"""
The Python built-in 'iter' doesn't explicityly handle functions with
arguments.  This variation accomplishes that by currying with lambda.

Re: [go-nuts] Re: Updating a struct from goroutines

2018-09-27 Thread Michael Ellis
Thanks for the feedback, Agni.  I think I may not have included enough
detail in my original post.

At present, the app is in the middle of transitioning to an all-Go
implementation.  For business reasons, that process will be stretched out
over the next several months or longer.  In the meantime, it needs to keep
working so I've already implemented something quite similar to what you
describe by porting the busiest Python processes first and providing a
socket interface that replaces the ZeroMQ interface in a way that allows
the calls from the remaining Python processes to have the same signature
and behavior as before.  That's working quite well so far and we're already
seeing better performance and improved reliability.

I should also mention that the target for the system is an inexpensive
Linux SBC, a Raspberry Pi.  In the pure Python version,  the overhead for
serializing, transmitting and de-serializing data had grown to use far more
CPU than seemed wise in a system that needs to run reliably for months at a
time at customer sites around the world.

Within the collection of processes that are now goroutines, I can't see a
benefit to incurring the overhead to marshal and unmarshal the data if
there's a concurrency-safe way to perform updates and get snapshots of the
state data.

Sending functions over a channel seems to be a match made in heaven for our
use cases.  It nicely supports our application logic that parcels out
responsibility for updating pieces of the state struct to long-running
goroutines.  Most of them are loops that fetch a snapshot of the state,
inspect it to make decisions about what actions to take, perform the
actions and update the state.

In that context, sending anonymous update functions wrapped in struct with
a disposable "done" channel doesn't seem overcomplicated at all.  The
update actions in my first post boil down to three lines that can be
wrapped up in a single function, e.g.

func Update(f func(*Big)) {
u := update{make(chan struct{}), f}
upch <- u // upch is a toplevel var visible to all goroutines
<-u.done
}

and an (oversimplified) goroutine that, say, reads a new value from a
sensor looks like

func gopher() {
var newA int
f := func(b *Big) {
b.A = newA
}
for {
newA = ReadSensor()
Update(f)
}
}

As I see it, the beauties of this approach are:

   1.  f is locally defined and therefore has access to gopher's locals,
   2. gopher has no direct access to the instance of Big that holds the
   state.
   3. Update pauses gopher until the state update has completed in the
   single goroutine that reads from upch.  So no worries about gopher changing
   its own locals before the update is complete.
   4. Benchmarking shows it's more than fast enough for our needs.
   5. The compiler catches any type mismatches instead of depending on the
   runtime to report it at deserialization.


Sorry for the long-winded reply. I really appreciate the feedback and the
opportunity to learn from you and others who've been using Go far longer
than I.







On Thu, Sep 27, 2018 at 12:48 AM Agniva De Sarker <
agniva.quicksil...@gmail.com> wrote:

> I think you are overcomplicating this a bit. It seems like a simple
> pattern of broadcasting a change to multiple agents. You send the change
> over a REQ-REP pair, and broadcast it to others over a PUB-SUB pair.
>
> Why do you need to copy the struct again ? Just get the struct from the
> REP socket and push it to the PUB socket ?
>
> Here is what I would do  -
>
> Use protobuf to marshal/unmarshal the config struct when sending/receiving
> it through the socket. That way you have perfect interop between Go and
> Python.
>
> And use a for-select pattern to do the job of receiving and broadcasting.
> Pseudo code as follows
>
> package main
>
> func main() {
> // setup REP socket in a goroutine, unmarshal the msg, send the struct to
> updateChan
> // create PUB socket, store it in mem somewhere
>
> go run()
>
> // setup signal handlers, and send signal to done chan when ctrl-c
> is received.
> }
>
> func run() {
> for {
> select {
> case msg := <-updateChan:
> // push msg to the PUB socket
> case <-done:
> // you have to send signal to this from main()
> return
> }
> }
> }
>
> Isn't this what you are trying to do ?
>
>
>
> On Wednesday, 26 September 2018 00:09:07 UTC+5:30, Michael Ellis wrote:
>>
>> Hi, new gopher here.
>> I considered asking this on SO, but they (rightly, IMO) discourage "Is
>> this a good way to do it?" questions.  Hope that's ok here.
>>
>> By way of background, I'm porting a largish industrial control
>> application from Python to Go.  The Python version uses multiple processes
>> (about a dozen in all) communicating over ZeroMQ.  One process, calle

Re: [go-nuts] Updating a struct from goroutines

2018-09-25 Thread Michael Ellis
Thanks, Justin. The struct in the real app is a flat collection of int, 
string, float64 and bool.  I appreciate the reminder,

On Tuesday, September 25, 2018 at 4:13:25 PM UTC-4, Justin Israel wrote:
>
>
>
> On Wed, Sep 26, 2018, 6:38 AM > wrote:
>
>> Hi, new gopher here. 
>> I considered asking this on SO, but they (rightly, IMO) discourage "Is 
>> this a good way to do it?" questions.  Hope that's ok here.
>>
>> By way of background, I'm porting a largish industrial control 
>> application from Python to Go.  The Python version uses multiple processes 
>> (about a dozen in all) communicating over ZeroMQ.  One process, called the 
>> statehouse,  controls access to the application state.  The others obtain 
>> copies and send updates over REQ sockets.  The data are serialized as JSON 
>> objects that map nicely to Python dicts.
>>
>> Since there's no direct equivalent in Go to a Python dict that can hold a 
>> mixture of arbitrary types,  I need to use a struct to represent the state. 
>> No problem with that but I've been struggling with how to allow the 
>> goroutines that will replace the Python processes to read and write to the 
>> state struct with concurrency safety.  
>>
>> This morning I came up with an idea to send functions over a channel to 
>> the main routine.  I put together a little test program and after some 
>> refinements it looks promising.  Some rough benchmarking shows I can get a 
>> million updates in under 1 second on a 2012 vintage Mac Mini.  That's more 
>> than good enough for this application where the time between events is 
>> usually more than 100 milliseconds.
>>
>> Here's the link to my test on the Go Playground: 
>> https://play.golang.org/p/8iWvwnqBNYl . It runs there except that the 
>> elapsed time comes back 0 and the prints from the second goroutine don't 
>> show up. I think that's got something to do with the artificial clock in 
>> the playground.  It works fine when I run it locally.  I've pasted the code 
>> at the bottom of this message.
>>
>> So my big questions are:
>>
>>- Is this actually concurrency safe as long as all goroutines only 
>>use the update mechanism to read and write?
>>- Is there a more idiomatic way to do it that performs as well or 
>>better?
>>- What are the potential problems if this is scaled to a couple dozen 
>>goroutines?
>>- Does it sacrifice clarity for cleverness? (not that it's all that 
>>clever, mind you, but I need to think about handing this off to my 
>> client's 
>>staff.)
>>
>>
>> Thanks very much,
>> Mike Ellis
>>
>> code follows ... 
>>
>> package main
>>
>> import (
>>  "fmt"
>>  "time"
>> )
>>
>>
>> // Big defines the application's state variables
>> type Big struct {
>>  A int
>>  B string
>>  /* and hundreds more */
>> }
>>
>>
>> // update is a struct that contains a function that updates a Big and
>> // a signal channel to be closed when the update is complete. An update
>> // may also be used to obtain a current copy of a Big by coding f to
>> // do so.  (See gopher2 below.)
>> type update struct {
>>  done chan struct{}
>>  ffunc(*Big)
>> }
>>
>>
>> // upch is a channel from which main receives updates.
>> var upch = make(chan update)
>>
>>
>> // gopher defines a function that updates a member of a Big and
>> // sends updates via upch. After each send it waits for main to
>> // close the update's done channel.
>> func gopher() {
>>  var newA int
>>  f := func(b *Big) {
>>  b.A = newA
>>  }
>>  for i := 0; i < n; i++ {
>>  newA = i
>>  u := update{make(chan struct{}), f}
>>  upch <- u
>>  <-u.done
>>  }
>> }
>>
>>
>> // gopher2 uses an update struct to obtain a current copy of a Big
>> // every 100 microseconds.
>> func gopher2() {
>>  var copied Big
>>  f := func(b *Big) {
>>  copied = *b
>>  }
>>  for {
>>  time.Sleep(100 * time.Microsecond)
>>  u := update{make(chan struct{}), f}
>>  upch <- u
>>  <-u.done
>>  fmt.Println(copied)
>>  }
>> }
>>
>>
>> // main creates a Big, launches gopher and waits on the update channel. 
>> When
>> // an update, u, arrives it runs u.f and then closes u.done.
>> func main() {
>>  var state = Big{-1, "foo"}
>>  fmt.Println(state) // --> {-1, "foo"}
>>  go gopher()
>>  go gopher2()
>>  start := time.Now()
>>  for i := 0; i < n; i++ {
>>  u := <-upch
>>  u.f()
>>  close(u.done)
>>  }
>>  perUpdate := time.Since(start).Nanoseconds() / int64(n) // Note: always 
>> 0 in playground
>>  fmt.Printf("%d updates, %d ns per update.\n", n, perUpdate)
>>  fmt.Println(state) // --> {n-1, "foo"}
>> }
>>
>>
>> var n = 1000 // number of updates to send and receive
>>
>>
> One aspect that may not be safe is that you copy the struct to use in 
> another goroutine. This is a shallow copy. If you only have immutable basic 
> types like ints and strings then this would be safe. But if your struct has 
> slices, maps, or pointers then you run the risk of mutating shared 
> references between two copies of the main struct. 
>
>
>>
>>  
>>
>> -- 
>> You received