share a certain amount of state, and be used further without interfering with each other. JavaScript example Using copy-on-write semantics, the JavaScript example from above becomes: class Kitten { constructor() { this.name = 'Garfield'; this.color = 'orange'; } setName(name) { const copy = new Kitten(); copy.color = this.color; copy.name = name; return copy; } setColor(color) { const copy = new Kitten(); copy.name = this.name; copy.color = color; return copy; } // ... } // use it const kitten1 = new Kitten() .setName('Salem'); const kitten2 = kitten1 .setColor('black'); console.log(kitten1, kitten2); // -> Kitten({ name: 'Salem', color: 'orange' }), Kitten({ name: 'Salem', color: 'black' }) Problems Errors cannot be captured at compile time In typed languages, using a constructor requiring all parameters will fail at compilation time while the fluent approach will only be able to generate runtime errors, missing all the type-safety checks of modern compilers. It also contradicts the "fail-fast" approach for error protection. Debugging and error reporting Single-line chained statements may be more difficult to debug as debuggers may not be able to set breakpoints within the chain. Stepping through a single-line statement in a debugger may also be less convenient. java.nio.ByteBuffer.allocate(10).rewind().limit(100); Another issue is that it may not be clear which of the method calls caused an exception, in particular if there are multiple calls to the same method. These issues can be overcome by breaking the statement into multiple lines which preserves readability while allowing the user to set breakpoints within the chain and to easily step through the code line by line: java.nio.ByteBuffer .allocate(10) .rewind() .limit(100); However, some debuggers always show the first line in the exception backtrace, although the exception has been thrown on any line. Logging Adding logging into the middle of a chain of fluent calls can be an issue. E.g., given: ByteBuffer buffer = ByteBuffer.allocate(10).rewind().limit(100); To log the state of buffer after the rewind() method call, it is necessary to break the fluent calls: ByteBuffer buffer = ByteBuffer.allocate(10).rewind(); log.debug("First byte after rewind is " + buffer.get(0)); buffer.limit(100); This can be worked around in languages that support extension methods by defining a new extension to wrap the desired logging functionality, for example in C# (using the same Java ByteBuffer example as above): static class ByteBufferExtensions { public static ByteBuffer Log(this ByteBuffer buffer, Log log, Action<ByteBuffer> getMessage) { string message = getMessage(buffer); log.debug(message); return buffer; } } // Usage: ByteBuffer .Allocate(10) .Rewind() .Log( log,