www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Imports with versions

reply "bearophile" <bearophileHUGS lycos.com> writes:
There are some updated on the Java-like language Ceylon:

http://ceylon-lang.org/blog/2012/10/29/ceylon-m4-analytical-engine/


One of the features of Ceylon that seems interesting are the 
module imports:

http://ceylon-lang.org/documentation/1.0/reference/structure/module/#descriptor


An example:

doc "An example module."
module com.example.foo 1.2.0 {
     import com.example.bar 3.4.1
     import org.example.whizzbang 0.5;
}


I think it helps avoid version troubles.

A possible syntax for D:

import std.random(2.0);
import std.random(2.0+);

Bye,
bearophile
Oct 29 2012
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-10-30 01:51, bearophile wrote:
 There are some updated on the Java-like language Ceylon:

 http://ceylon-lang.org/blog/2012/10/29/ceylon-m4-analytical-engine/


 One of the features of Ceylon that seems interesting are the module
 imports:

 http://ceylon-lang.org/documentation/1.0/reference/structure/module/#descriptor



 An example:

 doc "An example module."
 module com.example.foo 1.2.0 {
      import com.example.bar 3.4.1
      import org.example.whizzbang 0.5;
 }


 I think it helps avoid version troubles.

 A possible syntax for D:

 import std.random(2.0);
 import std.random(2.0+);

It probably wouldn't be a bad idea to have this but wouldn't it be better to have a package manger to handle this. -- /Jacob Carlborg
Oct 30 2012
parent reply Jacob Carlborg <doob me.com> writes:
On 2012-10-30 13:25, Paulo Pinto wrote:

 .NET and OSGi are similar approaches, because they rely on dynamic linking.

 The package manager only works with static linking, otherwise you might
 get into the situation it compiles fine, but runs into version conflicts
 when running. Common scenario to anyone doing Java development.

I would say, in this case, that you haven't specified the versions correctly.
 One issue both systems have problems solving is what to do when third
 party libraries have conflicting version requirements.

Yeah, this can be a problem. -- /Jacob Carlborg
Oct 30 2012
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-10-30 19:42, Paulo Pinto wrote:

 Not really.

 Let's say you compile everything fine, but on the deployment
 platform, some IT guy has the cool idea of changing some configuration
 settings.

 That change will have as side effect that some third party dependencies
 will now be matched to another version different than what was used by
 the package manager.

Again, then you haven't specified the dependencies correctly. If you just specify that "foo" depends on "bar" then you have only yourself to blame. You need to specify the exact version, i.e. "bar-1.2.3". If you cannot specify the exact version of an indirect dependency then you're not using a very good tools. RubyGems together with Bundler is a great package manager. You specify the direct dependencies of your software and the tool will write down all dependencies, direct and indirect, in a "locked" file, including all versions. When you deploy your software it will install and use the packages from the "locked" file. Your code cannot access any other dependencies that is not listed in the file.
 You'll spend a few hours trying to track down the issue, in case you
 forget about checking the dynamic resolution order.

 This is why Plan 9, Singularity and the Go guys are so much against
 dynamic linking.

One can always do stupid things, it can be quite hard to protect yourself from that. I mean, the IT guy can just replace your newly deployed application with a different version and no static linking in the world can help you there. -- /Jacob Carlborg
Oct 30 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-10-30 21:55, Paulo Pinto wrote:

 This cannot be enforced on runtime for most languages, that was why I
 was generalizing.

 For example C and C++ require the programmer to do this, somehow.

It's possible to change the path where a dynamic library is expected to be located after the application/library is compiled. The package manager can change this when installing a package.
 Java requires you bundled something like OSGi with your application.

 From the languages I have real project experience, only Groovy and .NET
 provide out of the box mechanisms for runtime validations given in the
 package manager.

It's one thing saying that your existing tools cannot handle this. It's an entirely different thing saying it's not possible. -- /Jacob Carlborg
Oct 31 2012
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-10-30 21:02, H. S. Teoh wrote:

 But doesn't that mean the version wasn't correctly depended upon?

 There should NEVER be generic dynamic library dependencies (i.e., "I can
 link with any version of libc"), because they are almost always wrong in
 some way. Maybe not obvious at first, but still wrong. They should
 always depend on the *exact* version (or versions) of a library.
 Anything else is fundamentally broken and will eventually cause
 headaches and sleepless nights.

 Mind you, though, a lot of libraries have a totally broken versioning
 system. Many library authors believe that the version only needs to be
 bumped when the API changes. Or worse, only when the existing API
 changes (new parts of the API are discounted.) That is actually wrong.
 The version needs to be bumped every time the *ABI* changes. An ABI
 change can include such things as compiling with different flags, or
 with a different compiler (*cough*gdc*dmd*cough*), *even when the source
 code hasn't been touched*. Any library that breaks this rule is
 essentially impossible to work with, because there is no way to
 guarantee that what gets linked at runtime is actually what you think it
 is.

 Unfortunately, in practice, both of the above are broken repeatedly.

I completely agree. See my answer about RubyGems and Bundler: http://forum.dlang.org/thread/ycigekrnsvjuulbxuxqr forum.dlang.org#post-k6pc33:241ma3:241:40digitalmars.com Packages in RubyGems are using Semantic Versioning: http://semver.org/ Which is supposed to help with these problems. But Ruby doesn't have a problem with breaking an ABI. -- /Jacob Carlborg
Oct 30 2012
prev sibling next sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Tuesday, 30 October 2012 at 08:44:48 UTC, Jacob Carlborg wrote:
 On 2012-10-30 01:51, bearophile wrote:
 There are some updated on the Java-like language Ceylon:

 http://ceylon-lang.org/blog/2012/10/29/ceylon-m4-analytical-engine/


 One of the features of Ceylon that seems interesting are the 
 module
 imports:

 http://ceylon-lang.org/documentation/1.0/reference/structure/module/#descriptor



 An example:

 doc "An example module."
 module com.example.foo 1.2.0 {
     import com.example.bar 3.4.1
     import org.example.whizzbang 0.5;
 }


 I think it helps avoid version troubles.

 A possible syntax for D:

 import std.random(2.0);
 import std.random(2.0+);

It probably wouldn't be a bad idea to have this but wouldn't it be better to have a package manger to handle this.

.NET and OSGi are similar approaches, because they rely on dynamic linking. The package manager only works with static linking, otherwise you might get into the situation it compiles fine, but runs into version conflicts when running. Common scenario to anyone doing Java development. One issue both systems have problems solving is what to do when third party libraries have conflicting version requirements. -- Paulo
Oct 30 2012
prev sibling next sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Tuesday, 30 October 2012 at 15:00:03 UTC, Jacob Carlborg wrote:
 On 2012-10-30 13:25, Paulo Pinto wrote:

 .NET and OSGi are similar approaches, because they rely on 
 dynamic linking.

 The package manager only works with static linking, otherwise 
 you might
 get into the situation it compiles fine, but runs into version 
 conflicts
 when running. Common scenario to anyone doing Java development.

I would say, in this case, that you haven't specified the versions correctly.

Not really. Let's say you compile everything fine, but on the deployment platform, some IT guy has the cool idea of changing some configuration settings. That change will have as side effect that some third party dependencies will now be matched to another version different than what was used by the package manager. You'll spend a few hours trying to track down the issue, in case you forget about checking the dynamic resolution order. This is why Plan 9, Singularity and the Go guys are so much against dynamic linking. -- Paulo
Oct 30 2012
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Oct 30, 2012 at 07:42:13PM +0100, Paulo Pinto wrote:
 On Tuesday, 30 October 2012 at 15:00:03 UTC, Jacob Carlborg wrote:
On 2012-10-30 13:25, Paulo Pinto wrote:
.NET and OSGi are similar approaches, because they rely on
dynamic linking.

The package manager only works with static linking, otherwise you
might get into the situation it compiles fine, but runs into version
conflicts when running. Common scenario to anyone doing Java
development.

I would say, in this case, that you haven't specified the versions correctly.

Not really. Let's say you compile everything fine, but on the deployment platform, some IT guy has the cool idea of changing some configuration settings. That change will have as side effect that some third party dependencies will now be matched to another version different than what was used by the package manager.

But doesn't that mean the version wasn't correctly depended upon? There should NEVER be generic dynamic library dependencies (i.e., "I can link with any version of libc"), because they are almost always wrong in some way. Maybe not obvious at first, but still wrong. They should always depend on the *exact* version (or versions) of a library. Anything else is fundamentally broken and will eventually cause headaches and sleepless nights. Mind you, though, a lot of libraries have a totally broken versioning system. Many library authors believe that the version only needs to be bumped when the API changes. Or worse, only when the existing API changes (new parts of the API are discounted.) That is actually wrong. The version needs to be bumped every time the *ABI* changes. An ABI change can include such things as compiling with different flags, or with a different compiler (*cough*gdc*dmd*cough*), *even when the source code hasn't been touched*. Any library that breaks this rule is essentially impossible to work with, because there is no way to guarantee that what gets linked at runtime is actually what you think it is. Unfortunately, in practice, both of the above are broken repeatedly. T -- We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the Internet, we know this is not true. -- Robert Wilensk
Oct 30 2012
prev sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Tuesday, 30 October 2012 at 20:08:04 UTC, Jacob Carlborg wrote:
 On 2012-10-30 19:42, Paulo Pinto wrote:

 Not really.

 Let's say you compile everything fine, but on the deployment
 platform, some IT guy has the cool idea of changing some 
 configuration
 settings.

 That change will have as side effect that some third party 
 dependencies
 will now be matched to another version different than what was 
 used by
 the package manager.

Again, then you haven't specified the dependencies correctly. If you just specify that "foo" depends on "bar" then you have only yourself to blame. You need to specify the exact version, i.e. "bar-1.2.3". If you cannot specify the exact version of an indirect dependency then you're not using a very good tools.

This cannot be enforced on runtime for most languages, that was why I was generalizing. For example C and C++ require the programmer to do this, somehow. Java requires you bundled something like OSGi with your application. From the languages I have real project experience, only Groovy and .NET provide out of the box mechanisms for runtime validations given in the package manager. -- Paulo
Oct 30 2012