Return-Path: X-Original-To: apmail-commons-dev-archive@www.apache.org Delivered-To: apmail-commons-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A8E6610F45 for ; Wed, 7 Aug 2013 18:23:59 +0000 (UTC) Received: (qmail 3161 invoked by uid 500); 7 Aug 2013 18:23:59 -0000 Delivered-To: apmail-commons-dev-archive@commons.apache.org Received: (qmail 2441 invoked by uid 500); 7 Aug 2013 18:23:56 -0000 Mailing-List: contact dev-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Commons Developers List" Delivered-To: mailing list dev@commons.apache.org Received: (qmail 2432 invoked by uid 99); 7 Aug 2013 18:23:55 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Aug 2013 18:23:55 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=5.0 tests=RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [193.74.71.27] (HELO eir.is.scarlet.be) (193.74.71.27) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Aug 2013 18:23:49 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scarlet.be; s=scarlet; t=1375899807; bh=5Xqvji7wEJkbJzN26jfQOXXh4dJaVjelB4OMzfyYl6E=; h=MIME-Version:Content-Type:Content-Transfer-Encoding:Date:From:To: Subject:Message-ID; b=lnOkTr8ofaDl8HcLRgRxuJg0VkSmhtd2krqKQD4t7ireOETUH0PaJ0nQ+3eQ5mlo7 GL1kLYbhSwVLEAZnL9+QjvlgQW1A4wLJLwXFax4LYVbmT80xU4uk495gNLEP9lgfhT krA/FHoJl/jiGe8LRtT/2dxQjj8BCx9D2/yPMXwk= Received: from webmail.scarlet.be (meigs.is.scarlet.be [193.74.71.216]) by eir.is.scarlet.be (8.14.5/8.14.5) with ESMTP id r77INQ0u017861 for ; Wed, 7 Aug 2013 20:23:27 +0200 X-Scarlet: d=1375899807 c=193.74.71.216 Received: from astropc12.ulb.ac.be ([164.15.125.60]) via astropc12.ulb.ac.be ([164.15.125.60]) by webmail.scarlet.be with HTTP (HTTP/1.1 POST); Wed, 07 Aug 2013 20:23:26 +0200 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Date: Wed, 07 Aug 2013 20:23:26 +0200 From: Gilles To: Subject: [Math] Fluent API, inheritance and immutability Message-ID: X-Sender: gilles@harfang.homelinux.org User-Agent: Scarlet Webmail X-DCC-scarlet.be-Metrics: eir; whitelist X-Virus-Scanned: clamav-milter 0.97.1-exp at eir X-Virus-Status: Clean X-Virus-Checked: Checked by ClamAV on apache.org Hi. It seems that each two of those concepts are at odds with the third one. E.g. you can have a fluent API and immutability, but this then prevents you from defining fluent API methods in a base class because immutability requires creating a new object (but the base class cannot know how to "build" a subclass). Dropping immutability would allow to define "withXxx" at the hierarchy level where they belong because the fluent methods modify instance fields (and return an existing "this"). Whereas keeping immutability requires that all "withXxx" are always redefined at the bottom level of the hierarchy. Also, if a base class is "abstract", no fluent method can be defined in it, since it cannot be instantiated. This also leads to the situation where the (re)initialization of fields that belong to the base class must be delegated to "withXxx" methods in all the subclasses. Thus, in this particular case, immutability entails code duplication. I wonder whether it would be possible to have the best of all worlds by 1. dropping immutability of the instance fields, 2. requiring that all classes participating in the fluent API implement a copy constructor, 3. requiring that all non abstract classes implement a "copy" method (whose contract is to return a fresh copy). Hence, code that would like to ensure that it is the sole owner of an object would be able to call the "copy" method on a mutable instance that would have been constructed with the fluent API. [One a side note: that proposal would also seem to reduce the overhead (however small that may be) of creating a new object for each modification, as well as allow usage in situations where creating a new instance would be undesirable e.g.: Applying a "withXxx" method on an object stored in a collection would create a local instance, and require that it be assigned back into the collection, preventing a language construct such as "foreach" loops.] I know that dropping immutability seems a step backwards from what were trying to achieve in Commons Math but it seems that we must let go of something (and security could be retained by unit tests that check the contract of "copy") If I'm missing something obvious, please let me know! Gilles --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org For additional commands, e-mail: dev-help@commons.apache.org