Skip to content
This repository has been archived by the owner on Nov 17, 2021. It is now read-only.

Why the ruby syntax? #5

Closed
voronoipotato opened this issue Sep 12, 2013 · 41 comments
Closed

Why the ruby syntax? #5

voronoipotato opened this issue Sep 12, 2013 · 41 comments

Comments

@voronoipotato
Copy link

I know this is a design decision, but I feel that it should be more like go. It seems less intuitive to have something written in go, for go, that looks like ruby simply because it was inspired by a ruby tool.

@trans
Copy link

trans commented Sep 12, 2013

Could use YAML ?

@voronoipotato
Copy link
Author

YAML might work actually. I'm not seeing any standard YAML go library but we could use libYAML.

@mattn
Copy link
Owner

mattn commented Sep 13, 2013

I think, yaml is good but yaml isn't DSL which people can judge the conditions as human readable.

@voronoipotato
Copy link
Author

We could literally just write it like go code. The problem with writing it like ruby is it makes an assumption that you know and are familiar with ruby code.

@trans
Copy link

trans commented Sep 13, 2013

You might be right, but lets see what we can do with the README example.

gom 'github.com/mattn/go-runewidth', :tag => 'go1'
gom 'github.com/mattn/go-scan', :commit => 'ecb144fb1f2848a24ebfdadf8e64380406d87206'
gom 'github.com/daviddengcn/go-colortext'
gom 'github.com/mattn/go-ole', :goos => 'windows'

Could be written:

- gom: github.com/mattn/go-runewidth
  tag: go1

- gom: github.com/mattn/go-scan
  commit: ecb144fb1f2848a24ebfdadf8e64380406d87206

- gom: github.com/daviddengcn/go-colortext

- gom: github.com/mattn/go-ole
  goos: windows

Personally I'd probably use more natural terms, like uri or dep instead of gom, and so forth, but that's a minor point.

If there is some concern that additional top-level info will be required one day, then adding a top-level mapping would do the trick. e.g.

dependencies:
- gom: ...

@trans
Copy link

trans commented Sep 13, 2013

Of course, thinking about it a bit more, you are using your own parser currently, so you could do it any way you wanted, which really does make the use of ruby symbols (e.g. :tag) seem a bit odd.

@trans
Copy link

trans commented Sep 13, 2013

What would the go code version look like?

@mattn
Copy link
Owner

mattn commented Sep 13, 2013

How about this in yaml?

group :production, :development do
  gom 'github.com/mattn/go-ole', :goos => 'windows'
end

@voronoipotato
Copy link
Author

There's also the encoding/json built in, which would definitely eliminate potential errors. However some readability would be lost. Then there's this https://github.com/emilsjolander/goson

@mattn
Copy link
Owner

mattn commented Sep 13, 2013

I don't think ruby's syntax is best for gom. but I think yaml is not better than ruby's syntax.

@trans
Copy link

trans commented Sep 13, 2013

I agree. If you need that level of expressiveness then it's either verbose XML or a DSL. If you want to do it in the most Go-ish way possible I suspect it would have to be by approximating functions and function chaining.

Gom("github.com/mattn/go-runewidth").Tag("go1")
Gom("github.com/mattn/go-scan").Commit("ecb144fb1f2848a24ebfdadf8e64380406d87206")
Gom("github.com/daviddengcn/go-colortext")
Gom("github.com/mattn/go-ole").Os("windows")

Group("production", "development") { 
  Gom("github.com/mattn/go-ole").Os("windows")
}

@gottwald
Copy link

What about a JSON file like Bower uses it?

Everybody knows JSON, it's easily extendable and go hast built-in support for it.

A definition file could look like this:

{
    dependencies: [
        {
            gom: "github.com/mattn/go-runewidth",
            tag: "go1"
        },
        {
            gom: "github.com/mattn/go-scan",
            commit: "ecb144fb1f2848a24ebfdadf8e64380406d87206"
        },
        {
            gom: "github.com/daviddengcn/go-colortext"
        },
        {
            gom: "github.com/mattn/go-ole",
            goos: "windows"
        },        
    ]
}

@trans
Copy link

trans commented Sep 19, 2013

I don't see any advantage to using JSON over YAML.

BTW http://theplant.github.io/pak/

@mattn
Copy link
Owner

mattn commented Sep 19, 2013

@trans pak seems not have condition like goos or production/development.

@trans
Copy link

trans commented Sep 19, 2013

I cam across QML for Go today. After looking at the QML, it reminded me of this issue b/c the QML looks a bit like Go (sort of like a GO and CSS hybrid). Given that, Gom could do something like:

Gom {
  uri: github.com/mattn/go-runewidth 
  tag: go1 
}

Gom { 
  uri: github.com/mattn/go-scan
  commit: ecb144fb1f2848a24ebfdadf8e64380406d87206
}

Gom { uri: github.com/daviddengcn/go-colortext }

Gom {
  uri: github.com/mattn/go-ole
  os: windows
}

Group production, development { 
  Gom { 
    uri: github.com/mattn/go-ole
    os: windows
  }
}

It looks more verbose, but entries could be condensed, e.g.

  Gom { uri: github.com/mattn/go-ole  os: windows }

as long as there are no spaces involved, in which case quotes would be necessary anyway I think. Either that or ; could used to separate entries on the same line.

I think this is better then the Ruby syntax in that it has a fairly Go look and feel.

@trans
Copy link

trans commented Sep 19, 2013

@mattn BTW, per your question about expressing the following in YAML.

group :production, :development do
  gom 'github.com/mattn/go-ole', :goos => 'windows'
end

I don't think there is really a particularly better way then just adding groups to each entry, e.g.

- gom: github.com/mattn/go-ole
  group: production, development
  os: windows

Redundant but simple.

@mattn
Copy link
Owner

mattn commented Sep 20, 2013

QML is too fat for gom.

BTW, per your question about expressing the following in YAML.

How do you write below in YAML? two section?

group :production, :development do
  gom 'github.com/daviddengcn/go-colortext-for-windows', :goos => [:windows]
  gom 'github.com/daviddengcn/go-colortext-for-linux', :goos => [:linux]
end

@trans
Copy link

trans commented Sep 20, 2013

@mattn Oh no, I wasn't suggesting you actually use QML! That was just my inspiration for the notation. I meant that the current parser could be modified to parse a syntax that was similar to QML's. Actually, it is very similar to CSS too, if that helps give a different perspective on it.

As for the YAML, you would do it like so:

- gom: github.com/daviddengcn/go-colortext-for-windows
  goos: [windows]
  group: [production, development]

- gom: github.com/daviddengcn/go-colortext-for-linux
  goos: [linux]
  group: [production, development]

Why goos and not just os, btw?

@voronoipotato
Copy link
Author

also I think dep instead of gom might be more descriptive.

@fern4lvarez
Copy link

+1 for JSON, since it's the only notation language supported natively by Go

@mattn
Copy link
Owner

mattn commented Sep 25, 2013

Go's JSON doesn't allow to write comment. It's too strictly.

@subosito
Copy link

@mattn what about if we using newer Ruby hash syntax:

gom 'github.com/mattn/go-scan', commit: 'ecb144fb1f2848a24ebfdadf8e64380406d87206'

Optionally, we can also drop "gom" keyword, so it will be:

github.com/mattn/go-scan, commit: 'ecb144fb1f2848a24ebfdadf8e64380406d87206'

And there is no symbol for the group:

group "production", "development" {
    github.com/mattn/go-scan, commit: 'ecb144fb1f2848a24ebfdadf8e64380406d87206'
{

or

group "production", "development":
    github.com/mattn/go-scan, commit: 'ecb144fb1f2848a24ebfdadf8e64380406d87206'

We can also define group as part of the line:

github.com/mattn/go-scan, commit: 'ecb144fb1f2848a24ebfdadf8e64380406d87206', group: "production, development"

What do you think?

@voronoipotato
Copy link
Author

The problem with using ruby syntax is there's no reason why any Go developer would be familiar with it. You lose all advantages of a DSL when you go outside the domain. We could also use lisp, or perl, or even haskell but those aren't going to be helpful but to a small subset of developers.

@fern4lvarez
Copy link

Surprised that no one gave a feedback on @trans Go-ish proposal on #5 (comment)
I'd change the Group curly braces by parentheses though, so it could be feasible to implement and idiomatic, too:

Gom("github.com/mattn/go-runewidth").Tag("go1")
Gom("github.com/mattn/go-scan").Commit("ecb144fb1f2848a24ebfdadf8e64380406d87206")
Gom("github.com/daviddengcn/go-colortext")
Gom("github.com/mattn/go-ole").Os("windows")

Group("production", "development") ( 
  Gom("github.com/mattn/go-ole").Os("windows")
)

In other hand, I know you guys probably see rubygems and bundle as the way to follow, but I don't really like having so similar specs and naming to Ruby. Thus, I'd just call .gom to the current Gomfile: cleaner, not intrusive and not intented to be a copy of anything.

EDIT

Another approach, totally OOP-ish:

Gom("github.com/mattn/go-runewidth").Tag("go1")
Gom("github.com/mattn/go-scan").Commit("ecb144fb1f2848a24ebfdadf8e64380406d87206")
Gom("github.com/daviddengcn/go-colortext")
Gom("github.com/mattn/go-ole").Os("windows")

Group("production", "development").Gom("github.com/mattn/go-ole").Os("windows")

@bronze1man
Copy link

+1 for yaml

@voronoipotato
Copy link
Author

I like the go function chaining style

@trans
Copy link

trans commented Sep 26, 2013

Just occurred to me that method chaining across newlines should be possible. So it could be written:

Gom("github.com/mattn/go-runewidth").
  Tag("go1")

Gom("github.com/mattn/go-scan").
  Commit("ecb144fb1f2848a24ebfdadf8e64380406d87206")

Gom("github.com/daviddengcn/go-colortext")

Gom("github.com/mattn/go-ole").
  Os("windows")

Group("production", "development").
  Gom("github.com/mattn/go-ole").
    Os("windows")

@mattn
Copy link
Owner

mattn commented Sep 26, 2013

I wrote example to use go syntax, hmm go is awsome but seems not useful to define DSL. . should be located at end of line. And compiler doesn't allow to locate . at leading of the line. gofmt breaks nesting for third line.

package main

import (
    "fmt"
)

var goms []*TGom

type TGroup struct {
    envs []string
}

type TGom struct {
    name   string
    commit string
    envs   []string
    os     []string
}

func Group(envs ...string) *TGroup {
    return &TGroup{envs}
}

func (group *TGroup) Gom(name string) *TGom {
    gom := &TGom{name, "", group.envs, []string{}}
    goms = append(goms, gom)
    return gom
}

func Gom(name string) *TGom {
    gom := &TGom{name, "", []string{}, []string{}}
    goms = append(goms, gom)
    return gom
}

func (gom *TGom) Commit(commit string) *TGom {
    gom.commit = commit
    return gom
}

func (gom *TGom) OS(os ...string) *TGom {
    gom.os = os
    return gom
}

func main() {
    Group("production", "development").
        Gom("github.com/mattn/go-ole").
            Commit("ecb144fb1f2848a24ebfdadf8e64380406d87206")

    Gom("github.com/mattn/go-ole").
        Commit("ecb144fb1f2848a24ebfdadf8e64380406d87206")

    for _, gom := range goms {
        fmt.Println(gom.name, gom.commit)
    }
}

@trans
Copy link

trans commented Sep 27, 2013

You might report the nesting issue as a bug in gofmt. Seems to me it should honor indentation.

@mattn
Copy link
Owner

mattn commented Sep 27, 2013

No, it's not a problem just for go. It's a related issue of identation for Gomfile.
For example, below is a valid indentaion for go.

a := NewSomething().
a.SetAttr("foo", "bar").
    SetAttr("bar", "baz").
    SetAttr("baz", "foo").

But Gomfile have a mean for indentation that different from go.

@trans
Copy link

trans commented Sep 27, 2013

It's valid but IMO if the design calls for such indention, e.g.

a := NewSomething().
a.SetAttr("foo", "bar").
    SetAttr("bar", "baz").
        SetAttr("baz", "foo")

Then gofmt needs to follow along and not make an assumption about what the significance of that indention is. In this particular case we know that SetAttr() is going to return a so indenting like this doesn't really make sense, but there is no way for gofmt to know that. If could be the SetAttr returned a new object every time instead, then this indention would make perfect sense and gofmt should leave it be.

@pkieltyka
Copy link

I like the gpm Godeps format.. https://github.com/pote/gpm

github.com/nu7hatch/gotrail               v0.0.2
github.com/replicon/fast-archiver         v1.02
launchpad.net/gocheck                     r2013.03.03   # Bazaar repositories are supported
code.google.com/p/go.example/hello/...    ae081cd1d6cc  # And so are Mercurial ones

@mattn
Copy link
Owner

mattn commented Mar 17, 2014

@pkieltyka The format can't define extra package. For example, packages just for windows.

@pkieltyka
Copy link

I see.. are people using a :platform directive to specify OS-specific libraries? I thought that would be handled by go's build tool via the standard // +build linux darwin etc

@mattn
Copy link
Owner

mattn commented Mar 18, 2014

Currently, gom gen gomfile doesn't handle that.

@pkieltyka
Copy link

I've also noticed a lot of Go developers using the classic INI format.. it's pretty clean: https://github.com/Unknwon/goconfig

This is what https://github.com/gpmgo/gopm does and it's nice .. their example:

[deps]
github.com/pilu/fresh=
github.com/astaxie/beego=tag:v0.9.0

you could do something like

[deps:windows]

[deps -windows +linux]
or whatever you come up with ..

@sporto
Copy link

sporto commented May 31, 2014

+1 for something in pure Go

Otherwise something in an standard format that can be written / read with external tooling e.g. JSON, JSON5, CSON, YAML

@ciarand
Copy link

ciarand commented Oct 26, 2014

https://github.com/hashicorp/hcl might also be an acceptable solution?

@tcurdt
Copy link

tcurdt commented Feb 14, 2015

Awkward discussion. Even if one doesn't know ruby it's still pretty simple to grasp the current syntax. I don't think the proposed syntax changes have much value other than "it should not remind me of ruby".

On the other hand machine readable would be nice - that's a fair point.
It's unfortunate that JSON doesn't allow for comments - but I would still vote for it.

Please no YAML.

@jinzhu
Copy link

jinzhu commented Feb 25, 2015

I don't see the value from the syntax change unless we could make it more readable, and don't like the idea to introduce another package to parse the configuration which could be done with only few lines of code.

@tranvictor
Copy link

I agree with @jinzhu, changing the Gomfile syntax produces more works with no remarkable value at this time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests